1

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

[Flags()]
public enum InvestmentAmount
{
    [Description("£500 - £5,000")]
    ZeroToFiveThousand,

    [Description("£5,000 - £10,000")]
    FiveThousandToTenThousand,

    //Deleted remaining entries for size

}

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

我试过自己滚动,但只是收到

当允许多选时,参数“表达式”的计算结果必须为 IEnumerable。

当它执行时。

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
    }
4

2 回答 2

3

查看我的博客文章,了解我为此创建的辅助方法:

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();  
    }  
}  
于 2013-07-25T11:54:04.433 回答
0

该错误似乎已经发生,因为我只绑定到一个“InvestmentAmount”,其中 ListFor 似乎检查模型是否是一个列表。

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

一个更好的解决方案是创建一个通用的 HTML ListFor 助手来完成它。如果我不止一次需要它,我会用哪种方式解决它。

于 2013-07-25T11:48:27.667 回答