Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolve metadata displayname from model metadata?

I have made a label extension with an additional 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?

like image 350
marcus Avatar asked Dec 17 '22 09:12

marcus


1 Answers

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.

like image 82
Major Byte Avatar answered Dec 19 '22 00:12

Major Byte