C# 枚举标志MVC.Net的列表
我的模型包含一个带有flags属性的枚举C# 枚举标志MVC.Net的列表,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我的模型包含一个带有flags属性的枚举 [Flags()] public enum InvestmentAmount { [Description("£500 - £5,000")] ZeroToFiveThousand, [Description("£5,000 - £10,000")] FiveThousandToTenThousand, //Deleted remaining entries for size } 我希望能够在视图中将其显示
[Flags()]
public enum InvestmentAmount
{
[Description("£500 - £5,000")]
ZeroToFiveThousand,
[Description("£5,000 - £10,000")]
FiveThousandToTenThousand,
//Deleted remaining entries for size
}
我希望能够在视图中将其显示为多选列表框。
显然,Listfor()的当前帮助程序不支持枚举
我试过自己滚,但刚收到
参数“expression”必须在以下情况下计算为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
}
public static MvcHtmlString EnumListFor(此HtmlHelper HtmlHelper、表达式、对象htmlAttributes)
{
ModelMetadata元数据=ModelMetadata.FromLambdaExpression(表达式,htmlHelper.ViewData);
类型enumType=GetNonNullableModelType(元数据);
IEnumerable values=Enum.GetValues(enumType.Cast();
IEnumerable items=来自值中的值
选择新的SelectListItem
{
Text=GetEnumDescription(值),
Value=Value.ToString(),
所选=value.Equals(metadata.Model)
};
//如果枚举可为空,请向集合中添加“空”项
if(metadata.IsNullableValueType)
items=SingleEmptyItem.Concat(项目);
RouteValueDictionary htmlattr=HtmlHelper.AnonymousObjectToHtmlatAttributes(HtmlatAttributes);
//添加(“多个”、“多个”);
if(expression.GetDescription()!=null)
{
Add(“数据内容”,expression.GetDescription());
添加(“数据原始标题”,expression.GetTitle());
htmlattr[“类”]=“指南”+htmlattr[“类”];
}
var fieldName=htmlHelper.NameFor(表达式).ToString();
返回htmlHelper.ListBox(fieldName,items,htmlattr);//此处抛出异常
}
出现错误似乎是因为我只绑定了一个“InvestmentAmount”,其中ListFor检查模型是否为列表
我不得不将模型更改为列表和内置绑定逻辑(通过AutoMapper),以便将标记的枚举转换为列表并返回
一个更好的解决方案是创建一个通用的HTML列表,以便帮助器执行此操作。如果我不止一次需要它,我会用这种方法来解决它。查看我的博客文章,我创建了一个助手方法来实现这一点: 这使您能够执行以下操作:
//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);
//如果没有枚举值,请使用类型
var enumList=EnumHelper.SelectListFor();
//如果确实有枚举值,请使用该值(该值将标记为选中)
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();
}
}
公共静态类EnumHelper
{
//为可为空的枚举值创建SelectList
公共静态SelectList SelectList for(T?已选)
其中T:struct
{
返回所选==null?SelectListFor()
:SelectListFor(selected.Value);
}
//为枚举类型创建SelectList
公共静态SelectList SelectListFor(),其中T:struct
{
类型t=类型(t);
if(t.IsEnum)
{
var values=Enum.GetValues(typeof(T)).Cast()
.Select(e=>new{Id=Convert.ToInt32(e),Name=e.GetDescription()});
返回新的SelectList(值“Id”、“Name”);
}
返回null;
}
//为枚举值创建SelectList
public static SelectList SelectListFor(T selected),其中T:struct
{
类型t=类型(t);
if(t.IsEnum)
{
var values=Enum.GetValues(t).Cast()
.Select(e=>new{Id=Convert.ToInt32(e),Name=e.GetDescription()});
返回新的SelectList(值“Id”、“Name”、Convert.ToInt32(选定));
}
返回null;
}
//如果
//枚举有一个,否则使用该值。
公共静态字符串GetDescription(此TEnum值)
{
FieldInfo fi=value.GetType().GetField(value.ToString());
如果(fi!=null)
{
DescriptionAttribute[]属性=
(DescriptionAttribute[])fi.GetCustomAttributes(
类型(描述属性),
假);
如果(attributes.Length>0)
{
返回属性[0]。说明;
}
}
返回值.ToString();
}
}
您可以发布引发异常的代码吗?您是否已将枚举列表转换为列表…?是的,我添加了一个我当前正在执行的操作的示例。这似乎只获取selectlist项,这是最容易解决的问题。真正的问题是绑定属性,以便在提交时写回。