3

ASP.Net MVC アプリケーションのビジネス オブジェクトに対して何らかの形式の属性を提供して、ビュー内のヘルプ テキストを取得し、ポップアップ ホバー ヘルプ テキストとして次のように表示するにはどうすればよいですか。

<%= Html.TextBox("PostalCode", Model.PostalCode, new { 
    title = "Please enter your postal code." })%>

ビジネス オブジェクトの属性からテキストを取得した ViewModel から「タイトル」値を取得できるようにしたいと考えています。

要約すると、ビジネス オブジェクトにヘルプ テキスト属性/メタデータを適用するにはどうすればよいですか?

4

4 に答える 4

2

これが私がやった方法です:

  1. 次のように新しい属性を作成しました。

    public class HelpPromptAttribute : Attribute
    {
      public HelpPromptAttribute(string text)
      {
          myproperty = text; 
      }
      protected string myproperty;
    
      public string HelpTextKey
      {
          get { return myproperty; }
          set { myproperty = value; }
      }
    }
    
  2. 次のようにエンティティ プロパティに属性を追加しました。

    [HelpPrompt("ProjectDescription")]
    [Required(ErrorMessageResourceName = "ProjectDescriptionRequired", ErrorMessageResourceType = typeof(EntityValidationMessages))]
    [StringLength(50, ErrorMessageResourceName = "ProjectDescriptionTooLong", ErrorMessageResourceType = typeof(EntityValidationMessages))]
    public string ProjectDescription { get; set; }
    
  3. 次のようにエンティティに拡張メソッドを追加しました。

    public static class EntityBOExtensions
    {
      public static string PropertyHelp(this object objectBO, string PropertyName)
      {
          Type type = objectBO.GetType();
    
    
          foreach (PropertyInfo pInfo in type.GetProperties())
          {
              if (string.Compare(pInfo.Name, PropertyName) == 0)
              {
                  foreach (Attribute attr in Attribute.GetCustomAttributes(pInfo))
                  {
                      if (attr.GetType() == typeof(HelpPromptAttribute))
                      {
                          string key = ((HelpPromptAttribute)attr).HelpTextKey;
                          if (!string.IsNullOrEmpty(key))
                              return EntityBOHelp.ResourceManager.GetString(key);
                      }
                  }
              }
          }
          return null;
      }
    }
    
  4. 次のように HtmlHelper (シンプル) を追加しました。

    public static string LocalisedTextBoxWithHelp(this HtmlHelper helper, string name, object value, string helptext)
    {
        string textbox = helper.TextBox(name, value, new { helpprompt = helptext });
        return textbox;
    }
    
  5. 最後に、ビューで次のマークアップを使用しました。

     <%= Html.LocalisedTextBoxWithHelp("project.ProjectDescription", Model.ProjectDescription, Model.PropertyHelp("ProjectDescription"))%>
    

洗練が必要ですが、これは仕事をします。;)

于 2009-10-01T17:55:01.920 に答える
1

箱から出してすぐにそれを行う方法はないと思います。

ただし、その情報をカプセル化する汎用の「モデル値」クラスを作成して、強く型付けされたビューを維持することができます。すなわち:

ModelValue<string> postalCode = new ModelValue<string>("poscode value", "Please enter your postal code.")

その後、ModelValue 型のプロパティを含むモデル クラスを作成できます。

上記のコードは次のようになります。

<%= Html.TextBox("PostalCode", Model.PostalCode.Value, new {     watermark = "Postal Code",     title = Model.PostalCode.Title })%>

これを行うことのマイナス面は、mvc が自動バインディングを行うとは思わないことです。そのため、この例のようにビュー内のすべてのマッピングを自分で行う必要がありますが、Post でも行う必要があります。まだ行っていない場合は、手動でバインドします。モデルのコンストラクターですべての ModelValue プロパティをインスタンス化し、それらが保存されている場所からすべてのタイトル値を取得することもおそらくあります。これは、Post でそれらを再バインドしないためです (ここで検証エラーが発生してフォームが再表示されます)。

あなたが非常に熱心であれば、モデルのプロパティに属性を設定し、ページをレンダリングするときに何らかの方法でそれらを解析するでしょうが、この方法で行きたい場合、どこから始めればよいかわかりません。

于 2009-10-01T01:16:44.790 に答える
1

I know this is old, but I faced this problem recently with an ASP.NET MVC3 project and implemented a solution.

1. Create a custom attribute to store the help text

public class HelpTextAttribute : DescriptionAttribute
{
    public HelpTextAttribute(string helpText)
        : base(helpText)
    { }
}

2. Create a HtmlHelper extension method to retrieve the attribute value

public static class HtmlHelperExtensions
{
    public static string HelpTextFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

        var attributes = memberExpression.Member.GetCustomAttributes(typeof(HelpTextAttribute), true);
        var attribute = attributes.Length > 0 ? attributes[0] as HelpTextAttribute : null;

        return html.Encode(attribute == null ? string.Empty : attribute.Description);
    }
}

3. Annotate the model property with the HelpText attribute

[HelpText("A level from which to start")]
[Required("You must select a level")]
public int Level { get; set; }

4. Simply use the new HtmlHelper extension method with your view

<div class="editor-help">
    <%: Html.HelpTextFor(model => model.Level) %>
</div>
于 2011-09-28T06:43:37.793 に答える
1

アップデート:

「Title」または「Hint」という名前のオブジェクトごとに新しいクラス プロパティを作成し、適切な文字列値を追加するだけです。次に、 MyObject.Title でそのプロパティを取得します


興味深い質問です。属性を使用してこれに対する答えを見たいのですが、考えられる2つの方法を次に示します。

オブジェクトに拡張メソッドを追加する これには、多くの繰り返しコードが必要になります。

public static string GetTitle(this YourObject obj)
{
     return "Title for object";
}

Html ヘルパー拡張メソッド

オブジェクトのタイトルをこのヘルパー メソッドに格納します。

public static string GetObjectTitle(this HtmlHelper html, string type)
{
     switch(type)
     {
          case "Object1":
          return "Title for object 1";
          break;

          case "Object2":
          return "Title for object 2";
          break;

          default:
          return "No titled specified for this object type";
          break;
     }
}

このメソッドを呼び出すには:

<%= Html.GetObjectTitle(Model.GetType()) %>

またはあなたの例では:

<%= Html.TextBox("PostalCode", Model.PostalCode, new { 
watermark = "Postal Code", 
title = Html.GetObjectTitle(Model.GetType()) })%>

すべてのタイトルを保存する場所があり、記述するコードが少なくて済むため、2 番目の方法をお勧めします。

ただし、クラスに属性を追加して、その属性を取得する手段を作成すると、もう少しうまくいくと思います。

于 2009-10-01T01:11:33.693 に答える