0

I have a model-based DescriptionFor helper that looks like this:

public static HtmlString DescriptionFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression) where TModel : class
{
    var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    return new HtmlString(metaData.Description.ToStringOrEmpty());
}

This keys off the DataAnnotations.DisplayAttribute (specifically, the Description parameter) and it works swimmingly.

I have a case now where my model has an IEnumerable<foo> that I am looping through, and foo has an enum with DisplayAttributes for each enum member. Most, but not all, of the DisplayAttribute attributes have provided a Description property, and I want to expose that in my loop like so:

@foreach(var fooObject in Model.foos){ 
    @Html.Description(fooObject, x=>x.fooEnumVal)
}

...where this would display the enum value description for each foo object.

I quickly discovered that it was not very similar to the model helper. Can someone point me in the right direction for this?

Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254

2 Answers2

0

You can use for loop instead of foreach and get description with your helper

@for(int i =0; i < Model.foos.Count(); i++){ 
    @Html.Description(x => x.foos[i].fooEnumVal)
}

Also you can create new helper method which will create new viewdatadictionary for the specified model and get metadata for property (I haven't check it but it should work :) )

public static HtmlString DescriptionFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, TModel model, Expression<Func<TModel, TProperty>> expression) 
            where TModel : class
        {
            var metaData = ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>(model));
            return new HtmlString(metaData.Description.ToStringOrEmpty());
        }

Hope it helps

Denis Borovnev
  • 486
  • 3
  • 3
0

I ended up doing something like this:

public static HtmlString DescriptionFor(this Enum theEnum)
{
    var theEnumType = theEnum.GetType();

    //the enum must inherit from Enum, but not actually *be* Enum.
    if (!(theEnum is Enum) || theEnumType.Equals(typeof(Enum))) throw new ArgumentException("Not a valid Enumeration.");

    var fi = theEnumType.GetField(theEnum.ToString());
    var displayAttribute = ((DisplayAttribute[])fi.GetCustomAttributes(typeof(DisplayAttribute), false))
        .FirstOrDefault();

    if (displayAttribute == null) return new HtmlString(theEnum.ToString());

    return new HtmlString(displayAttribute.Description ?? theEnum.ToString());
}

I'm sure this is not the best way, but I was able to effectively write in my view:

@fooObject.enumVal.DescriptionFor()

which performed as I desired.

Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254