2011-09-10 13 views
3

追加のパラメータを使用してラベル拡張を作成しましたが、ViewData.ModelMetadata.DisplayNameを使用すると、モデルのDiaplsy属性から表示名を取得できません。メタデータの表示名をモデルのメタデータから解決しますか?

私のモデルは、この

[Display(Name = "User name")] 
    public string UserName { get; set; } 

のようなユーザ名を持っており、このHTMLヘルパー

public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex, Func<object, HelperResult> template, string labelText = null) { 
     var htmlFieldName = ExpressionHelper.GetExpressionText(ex); 
     var metadata = htmlHelper.ViewData.ModelMetadata; 
     string resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
     if (String.IsNullOrEmpty(resolvedLabelText)) { 
      return MvcHtmlString.Empty; 
     } 

     var tag = new TagBuilder("label"); 
     tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName))); 
     tag.InnerHtml = string.Format(
      "{0} {1}", 
      resolvedLabelText, 
      template(null).ToHtmlString() 
     ); 
     return MvcHtmlString.Create(tag.ToString()); 
    } 

この

@Html.LabelFor(m => m.SetupModel.UserName, @<span>No fancy characters mmkay?</span>) 

のように使用されているが、結果はUserNameNo空想の文字がmmkayのですか?私はそれが表示属性に設定された名前を表示する必要があると思ったとき?

答えて

8

以前の回答を投稿したときに、あなたがビューモデル内に異なるオブジェクトを持っているという事実を忘れました。以下はアイデアを説明するためのものですが、これを行うためのより良い方法があるはずです。

var metadata = ModelMetadata.FromLambdaExpression(ex, htmlHelper.ViewData); 
var resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 

string resolvedLabelText = ""; 
if (htmlFieldName.Contains('.')) 
{ 
    var model = htmlFieldName.Split('.'); 

    var metadata = htmlHelper.ViewData.ModelMetadata.Properties.FirstOrDefault(p => p.PropertyName == model[0]); 
    if (metadata != null) 
    { 
     metadata = metadata.Properties.FirstOrDefault(p => p.PropertyName == model[1]); 
     resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
    } 
    else 
     resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
} 
else 
{ 
    var metadata = htmlHelper.ViewData.ModelMetadata.Properties.First(p => p.PropertyName == htmlFieldName); 
    resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
} 

上記は、例えばSomeObject.SomeObject.Properyために動作しません:

これはトリックです。

+0

MVC4中の場合には、私は、このビューでは、私が使用したモデルが構成モデルとRegisterModelが含まれているタイプのSetupViewModelであるため、シーケンスが一致する要素例外が含まれていません取得します。提案されたコードクエリは、 "SetupModel.UserName"という名前のプロパティです。 パブリッククラスSetupViewModel { public Configuration.Configuration Configuration {get;セット; } public RegisterModel SetupModel {get;セット; } } – Marcus

+0

私は自分の答えを更新しました。正しい軌道に乗るだけです。あなたの例ではうまくいくでしょうが、それだけです。メタデータはネストされていると言います。 –

+0

ありがとう、それはやりました。あなたが言ったように、これはもっと良い方法がなければならないように感じるので、どの物件にも作用します。 – Marcus

4

ただ、その非常に単純な

@ViewData.ModelMetadata.PropertyName 
@ViewData.ModelMetadata.DisplayName 
関連する問題