Resolve metadata displayname from model metadata?
I have made a label extension with an ad开发者_如何转开发ditional parameter but when I use ViewData.ModelMetadata.DisplayName I don't get the display name from the Diaplsy attribute on my model?
My model has a username like this
[Display(Name = "User name")]
public string UserName { get; set; }
and is used like this
@Html.LabelFor(m => m.SetupModel.UserName, @<span>No fancy characters mmkay?</span>)
with this html helper
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());
}
But the result is UserNameNo fancy characters mmkay? when I thought it should show the name set in the display attribute?
I missed the fact that you have different objects inside your viewmodel when I posted my previous answer. The following is just to illustrate the idea, there should be a better way to do this.
This is the trick:
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();
}
The above will not work for SomeObject.SomeObject.Propery
for instance.
Just in case in MVC4 its very simple
@ViewData.ModelMetadata.PropertyName
@ViewData.ModelMetadata.DisplayName
精彩评论