2011-09-10 40 views
3

我已经做了一个额外的参数标签扩展,但是当我使用ViewData.ModelMetadata.DisplayName我没有从我的模型上的Diaplsy属性显示名称?从模型元数据解析元数据显示名称?

我的模型有这样

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

一个用户名,并使用类似这样的

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

与此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()); 
    } 

但结果是UserNameNo看中字符mmkay?当我认为它应该显示在显示属性中设置的名称?

回答

8

我错过了当我发布我以前的答案时,您的viewmodel中有不同的对象。以下只是为了说明这个想法,应该有更好的方法来做到这一点。

这是招:

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

我得到一个序列中没有匹配的元素异常,因为我在这个视图中使用的模型是含有配置模型和RegisterModel型SetupViewModel的。建议的代码查询的属性名称为“SetupModel.UserName”。 public class SetupViewModel public Configuration.Configuration Configuration {get;组; } public RegisterModel SetupModel {get;组; } } – Marcus

+0

我更新了我的答案,只是为了让你走上正轨,它会在你的榜样中起作用,但就是这样。元数据是嵌套的,所以说... –

+0

谢谢,这是做的伎俩。正如你所说,感觉好像有一个更好的方法来做到这一点,所以它也适用于任何财产。 – Marcus

4

万一在MVC4它很简单

@ViewData.ModelMetadata.PropertyName 
@ViewData.ModelMetadata.DisplayName