C# 使用复选框回发带有标志的枚举
我有一个枚举属性,我正试图通过复选框设置它的值。枚举被标记,当用户选择多个选项时,我希望属性将所有选定的标记连接起来 我尝试为每个枚举值添加一个复选框,并为每个复选框指定相同的名称。回发期间,将检索第一个选定标志,但不会与其他标志连接 我是否可以在每个标志没有单独属性的情况下以某种方式修复此问题 模型 看法C# 使用复选框回发带有标志的枚举,c#,asp.net-mvc,enums,enum-flags,C#,Asp.net Mvc,Enums,Enum Flags,我有一个枚举属性,我正试图通过复选框设置它的值。枚举被标记,当用户选择多个选项时,我希望属性将所有选定的标记连接起来 我尝试为每个枚举值添加一个复选框,并为每个复选框指定相同的名称。回发期间,将检索第一个选定标志,但不会与其他标志连接 我是否可以在每个标志没有单独属性的情况下以某种方式修复此问题 模型 看法 如果您检查发送数据的邮件正文,则无法正确拾取数据。这是因为MVC不能很好地处理标志枚举。有人提出了类似的问题: 通常,我在设计视图模型时避免使用枚举,因为它们不使用ASP.NET MVC的帮
如果您检查发送数据的邮件正文,则无法正确拾取数据。这是因为MVC不能很好地处理标志枚举。有人提出了类似的问题: 通常,我在设计视图模型时避免使用枚举,因为它们不使用ASP.NET MVC的帮助程序和现成的模型绑定器。它们在您的域模型中非常好,但对于视图模型,您可以使用其他类型 在这里,回答问题的人还提供了如何绑定标志枚举的完整答案。您基本上需要做的是创建自己的自定义模型绑定器,该绑定器可以处理标记枚举。在另一篇名为“我发现了一个示例”的帖子中,我将复制相关代码 添加名为
CustomModelBinder
的类,如下所示:
public class CustomModelBinder : DefaultModelBinder
{
protected override object GetPropertyValue(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor,
IModelBinder propertyBinder)
{
var propertyType = propertyDescriptor.PropertyType;
// Check if the property type is an enum with the flag attribute
if (propertyType.IsEnum && propertyType.GetCustomAttributes(true).Any())
{
var providerValue = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
if (providerValue != null)
{
var value = providerValue.RawValue;
if (value != null)
{
// In case it is a checkbox list/dropdownlist/radio
// button list
if (value is string[])
{
// Create flag value from posted values
var flagValue = ((string[])value)
.Aggregate(0, (acc, i)
=> acc | (int)Enum.Parse(propertyType, i));
return Enum.ToObject(propertyType, flagValue);
}
// In case it is a single value
if (value.GetType().IsEnum)
{
return Enum.ToObject(propertyType, value);
}
}
}
}
return base.GetPropertyValue(controllerContext,
bindingContext,
propertyDescriptor,
propertyBinder);
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register custom flag enum model binder
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
}
然后在Global.asax.csApplication\u Start
方法中注册自定义模型绑定器,如下所示:
public class CustomModelBinder : DefaultModelBinder
{
protected override object GetPropertyValue(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor,
IModelBinder propertyBinder)
{
var propertyType = propertyDescriptor.PropertyType;
// Check if the property type is an enum with the flag attribute
if (propertyType.IsEnum && propertyType.GetCustomAttributes(true).Any())
{
var providerValue = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName);
if (providerValue != null)
{
var value = providerValue.RawValue;
if (value != null)
{
// In case it is a checkbox list/dropdownlist/radio
// button list
if (value is string[])
{
// Create flag value from posted values
var flagValue = ((string[])value)
.Aggregate(0, (acc, i)
=> acc | (int)Enum.Parse(propertyType, i));
return Enum.ToObject(propertyType, flagValue);
}
// In case it is a single value
if (value.GetType().IsEnum)
{
return Enum.ToObject(propertyType, value);
}
}
}
}
return base.GetPropertyValue(controllerContext,
bindingContext,
propertyDescriptor,
propertyBinder);
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register custom flag enum model binder
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
}
这应该行得通
资料来源:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register custom flag enum model binder
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
}