getting description with EnumDropDownListFor asp.net mvc5

5

How do I get the description using the Asp.net MVC 5 html EnumDropDownListFor helper?

I have my enumerator

public num Dias {
      [Description("Segunda dia de trabalho")]
      Segunda = 1,
      [Description("Terçadia de trabalho")]
      Terca = 2
}

When I use the html asp.net mvc5 helper

 @Html.EnumDropDownListFor(x => x.Dias);

It returns me the values: "Monday, Tuesday", I would like to return the values of the Description in my select

    
asked by anonymous 28.08.2014 / 16:12

3 answers

3

I've rewritten the extensive static method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
namespace System.Web.Mvc
{
    public static class MethodsExtensivos
    {
        public static System.Web.Mvc.MvcHtmlString EnumDropDownListDescriptionFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string label = null, object htmlAttributes = null)            
        {
            TModel model = htmlHelper.ViewData.Model;
            TProperty property = default(TProperty);
            if (model != null)
            {
                Func<TModel, TProperty> func = expression.Compile();
                property = func(model);
            }
            TagBuilder select = new TagBuilder("select");            
            if (htmlAttributes != null)
            {
                System.Reflection.PropertyInfo[] properties = htmlAttributes.GetType().GetProperties();
                foreach (System.Reflection.PropertyInfo prop in properties)
                {
                    select.MergeAttribute(prop.Name, (String)prop.GetValue(htmlAttributes, null));
                }
            }            
            Type type = typeof(TProperty);            
            String[] Names = type.GetEnumNames();
            if (label != null)
            {
                TagBuilder option = new TagBuilder("option");
                option.MergeAttribute("value", "0");
                option.InnerHtml = label;
                select.InnerHtml += option.ToString();
            }            
            foreach(string Name in Names) {
                System.Reflection.MemberInfo info = type.GetMember(Name).FirstOrDefault();
                TagBuilder option = new TagBuilder("option");
                if (property != null && property.ToString().Equals(Name))
                {
                    option.MergeAttribute("selected", "selected");
                }
                option.MergeAttribute("value", ((int)Enum.Parse(typeof(TProperty), Name)).ToString());
                var texto = info.CustomAttributes
                        .Select(x => x.ConstructorArguments.Select(a => a.Value))
                        .FirstOrDefault();
                if (texto != null)
                {
                    option.SetInnerText(texto.FirstOrDefault().ToString());
                }
                else
                {
                    option.SetInnerText(Name);
                }
                select.InnerHtml += option.ToString();
            }
            if (!select.Attributes.Where(x => x.Key.ToLower().Equals("id")).Any())
            {
                select.MergeAttribute("id", type.Name);

            }
            if (!select.Attributes.Where(x => x.Key.ToLower().Equals("name")).Any())
            {
                select.MergeAttribute("name", type.Name);
            }
            return MvcHtmlString.Create(select.ToString());
        }            
    }
}

Scheduling this code:

@Html.EnumDropDownListDescriptionFor(a => a.Dias)
@Html.EnumDropDownListDescriptionFor(a => a.Dias, "Escolha do Dia da Semana")
@Html.EnumDropDownListDescriptionFor(a => a.Dias, "Escolha do Dia da Semana", new { id="select1", name="select1", css="style1" })

Result:

<selectid="Dias" name="Dias">
  <option value="10">Segunda dia de trabalho</option>
  <option selected="selected" value="20">Ter&#231;a dia de trabalho</option>
</select>
<select id="Dias" name="Dias">
  <option value="0">Escolha do Dia da Semana</option>
  <option value="10">Segunda dia de trabalho</option>
  <option selected="selected" value="20">Ter&#231;a dia de trabalho</option>
</select>
<select css="style1" id="select1" name="select1">
  <option value="0">Escolha do Dia da Semana</option>
  <option value="10">Segunda dia de trabalho</option>
  <option selected="selected" value="20">Ter&#231;a dia de trabalho</option>
</select>
    
28.08.2014 / 19:21
9

An alternative I found is to use annotation

[Display(Name = "Valor")]

In it the Html Helper itself recognizes the values, not having to do anything more than that

    
28.08.2014 / 17:42
1

I use this extension method:

public static string GetEnumDescription(this Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =
        (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute),
        false);

    if (attributes != null &&
        attributes.Length > 0)
        return attributes[0].Description;
    else
        return value.ToString();
}

It allows you to retrieve the values for later popular dropdown like this:

var listaParaDropDown = from EMeuEnum in Enum.GetValues(typeof(EMeuEnum ))
                        select new { Id = e, Nome = e.GetEnumDescription() };

Fill in the dropdown from this list.

    
28.08.2014 / 18:53