ListFor枚举标志MVC.Net

本文关键字:Net MVC 标志 枚举 ListFor | 更新日期: 2023-09-27 18:24:35

我的模型包含一个带有标志属性的枚举

[Flags()]
public enum InvestmentAmount
{
    [Description("£500 - £5,000")]
    ZeroToFiveThousand,
    [Description("£5,000 - £10,000")]
    FiveThousandToTenThousand,
    //Deleted remaining entries for size
}

我希望能够在我的视图中将其显示为多选项列表框。显然,Listfor()的当前帮助程序不支持枚举。

我试过自己滚动,但刚刚收到

当允许多选。

当它执行时。

public static MvcHtmlString EnumListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        Type enumType = GetNonNullableModelType(metadata);
        IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
        IEnumerable<SelectListItem> items = from value in values
                                            select new SelectListItem
                                            {
                                                Text = GetEnumDescription(value),
                                                Value = value.ToString(),
                                                Selected = value.Equals(metadata.Model)
                                            };
        // If the enum is nullable, add an 'empty' item to the collection
        if (metadata.IsNullableValueType)
            items = SingleEmptyItem.Concat(items);

        RouteValueDictionary htmlattr = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        //htmlattr.Add("multiple", "multiple");
        if (expression.GetDescription() != null)
        {
            htmlattr.Add("data-content", expression.GetDescription());
            htmlattr.Add("data-original-title", expression.GetTitle());
            htmlattr["class"] = "guidance " + htmlattr["class"];
        }
        var fieldName = htmlHelper.NameFor(expression).ToString();
        return htmlHelper.ListBox(fieldName, items, htmlattr); //Exception thrown here
    }

ListFor枚举标志MVC.Net

查看我的博客文章,了解我为实现这一点而创建的助手方法:

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

这使你可以做这样的事情:

//If you don't have an enum value use the type  
var enumList = EnumHelper.SelectListFor<MyEnum>();  
//If you do have an enum value use the value (the value will be marked as selected)  
var enumList = EnumHelper.SelectListFor(myEnumValue);

然后您可以使用它来构建您的多列表。

助手类如下:

public static class EnumHelper  
{  
    //Creates a SelectList for a nullable enum value  
    public static SelectList SelectListFor<T>(T? selected)  
        where T : struct  
    {  
        return selected == null ? SelectListFor<T>()  
                                : SelectListFor(selected.Value);  
    }  
    //Creates a SelectList for an enum type  
    public static SelectList SelectListFor<T>() where T : struct  
    {  
        Type t = typeof (T);  
        if (t.IsEnum)  
        {  
            var values = Enum.GetValues(typeof(T)).Cast<enum>()  
                             .Select(e => new { Id = Convert.ToInt32(e), Name = e.GetDescription() });  
            return new SelectList(values, "Id", "Name");  
        }  
        return null;  
    }  
    //Creates a SelectList for an enum value  
    public static SelectList SelectListFor<T>(T selected) where T : struct   
    {  
        Type t = typeof(T);  
        if (t.IsEnum)  
        {  
            var values = Enum.GetValues(t).Cast<Enum>()  
                             .Select(e => new { Id = Convert.ToInt32(e), Name = e.GetDescription() });  
            return new SelectList(values, "Id", "Name", Convert.ToInt32(selected));  
        }  
        return null;  
    }   
    // Get the value of the description attribute if the   
    // enum has one, otherwise use the value.  
    public static string GetDescription<TEnum>(this TEnum value)  
    {  
        FieldInfo fi = value.GetType().GetField(value.ToString());  
        if (fi != null)  
        {  
            DescriptionAttribute[] attributes =  
             (DescriptionAttribute[])fi.GetCustomAttributes(  
    typeof(DescriptionAttribute),  
    false);  
            if (attributes.Length > 0)  
            {  
                 return attributes[0].Description;  
            }  
        }  
        return value.ToString();  
    }  
}  

出现错误的原因似乎是我只绑定到了一个"InvestmentAmount",此时ListFor会检查模型是否为列表。

我不得不将我的模型更改为List并内置绑定逻辑(通过AutoMapper),以便从标记的Enum转换为List并返回。

一个更好的解决方案是创建一个通用的HTMLListFor助手来完成这项工作。如果我多次需要它,这就是我处理它的方法。