-1

I am trying to access a model's metadata attributes to create a helper to automatically add HtmlAttributes based on DataAnnotations.

Problem is, the attributes are always empty.

I have 2 basic classes to try on an empty project:

namespace MegaInterestingProject
{
    public class HomeController : Controller
    {
        public string Index()
        {
            var model = ModelMetadata.FromLambdaExpression<HomeModel, string>(x => x.User, new ViewDataDictionary<HomeModel>());

            return model.Description;
        }
    }

    public class HomeModel
    {
        [Required]
        [MaxLength(13)]
        [MinLength(11)]
        [DisplayName("displayname")]
        [Description("description")]
        public string User { get; set; }
    }
}

Here model.Description is always empty and the AdditionalValues dictionary is always empty.

Maybe something is missing here?

Here is a reference project I added on GitHub: https://github.com/erickgirard/TestHtmlAttributesHelper

Cœur
  • 37,241
  • 25
  • 195
  • 267
Erick
  • 5,969
  • 10
  • 42
  • 61

2 Answers2

2

Your using the wrong attribute for generating the ModelMetadata. You need to use the DisplayAttribute in System.ComponentModel.DataAnnotations (not DisplayNameAttribute in System.ComponentModel.

public class HomeModel
{
  [Display(Name = "displayname", Description = "description")]
  public string User { get; set; }
}
0

You did not place the attribute on the model, but on a property of a model.

A custom helper function that accesses the metadata of a property within a model would look like this:

public static MvcHtmlString CustomHelperFunctionFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
    var propertyName = ExpressionHelper.GetExpressionText(expression);
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var displayname = metadata.DisplayName;
    var description = metadata.Description;

    return new MvcHtmlString("have fun!");
}
souplex
  • 981
  • 6
  • 16
  • Why do you declare a propertyName variable ? You don't seem to use it actually? Beside, I've gone the generic way and already done an extension method using this structure, but the properties where still empty. – Erick Jun 19 '14 at 19:28
  • True, this was some code from one of my actual functions which I pasted over and modified for illustration. But I left it in to to illustrate how you know which of the properties in your model you are actually working with. This is code for an html helper function you can use to extend @Htmlhelper. But the main point is: you are trying to read the metadata from the model level, while the actual attribute values reside on model.property level. – souplex Jun 19 '14 at 19:37
  • I did a copy and paste of your code. Still empty. I've edited my first post with a test project on github – Erick Jun 19 '14 at 19:47
  • Good thinking, submitted the pull request. – souplex Jun 19 '14 at 20:04
  • The merge was useful for display and description maybe, but the core problem (the AdditionalValues dictionary was empty) is still there. I still can't access MaxLength attribute or any other attribute. – Erick Jun 19 '14 at 20:13
  • The Min/Max attributes are truely confusing, we are supposed to use stringlength for this. Required was working fine. See the merge. – souplex Jun 19 '14 at 20:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/55940/discussion-between-souplex-and-erick). – souplex Jun 19 '14 at 20:30