有没有办法有绑定到一个List&LT当DefaultModelBinder忽略空项目;枚举&GT; [英] Is there a way to have the DefaultModelBinder ignore empty items when binding to a List<Enum>
问题描述
我有一种情况,我想改变它是如何结合枚举的列表DefaultModelBinder的行为。
我有一个枚举...
公共枚举MyEnum {FirstVal,SecondVal,ThirdVal}
和一个模型类...
公共类为MyModel
{
公开名单&LT; MyEnum&GT; MyEnums {搞定;组; }
}
和POST身体...
MyEnums =安培; MyEnums = ThirdVal
目前,模型绑定之后,MyEnums属性将包含...
[0] = FirstVal
[1] = ThirdVal
是有办法告诉模型绑定忽略已发布数据的空值,以便MyEnums财产可能看起来像下面的?
[0] = ThirdVal
您可以写为MyModel自定义模型绑定:
公共类MyModelModelBinder:DefaultModelBinder
{
保护覆盖无效的SetProperty(
ControllerContext controllerContext,
ModelBindingContext BindingContext中,
的PropertyDescriptor PropertyDescriptor的,
对象值)
{
如果(值的ICollection&LT; MyEnum&GT;)
{
VAR myEnums = controllerContext.HttpContext.Request [propertyDescriptor.Name]
如果(!string.IsNullOrEmpty(myEnums))
{
VAR令牌= myEnums.Split(新[] {','},StringSplitOptions.RemoveEmptyEntries);
值= tokens.Select(X =&GT;(MyEnum)Enum.Parse(typeof运算(MyEnum),X))了ToList();
}
}
base.SetProperty(controllerContext,BindingContext中,PropertyDescriptor的,价值);
}
}
这是在的Application_Start
注册
保护无效的Application_Start()
{
AreaRegistration.RegisterAllAreas();
的RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof运算(为MyModel),新MyModelModelBinder());
}
更新:
由于在评论部分要求这里是如何使previous粘结剂更通用的:
保护覆盖无效的SetProperty(
ControllerContext controllerContext,
ModelBindingContext BindingContext中,
的PropertyDescriptor PropertyDescriptor的,
对象值)
{
VAR收集=值作为IList的;
如果(集合= NULL&放大器;!&安培; collection.GetType()IsGenericType。)
{
VAR genericArgument =集合
.GetType()
.GetGenericArguments()
。凡(T =&GT; t.IsEnum)
.FirstOrDefault(); 如果(genericArgument!= NULL)
{
collection.Clear();
VAR enumValues = controllerContext.HttpContext
.Request [propertyDescriptor.Name]
VAR令牌= enumValues.Split(
新的[] {','},StringSplitOptions.RemoveEmptyEntries);
的foreach(在令牌VAR令牌)
{
collection.Add(Enum.Parse(genericArgument,令牌));
}
}
}
base.SetProperty(controllerContext,BindingContext中,PropertyDescriptor的,价值);
}
I have a scenario where I'd like to change the behavior of the DefaultModelBinder in how it binds to a List of enums.
I have an enum...
public enum MyEnum { FirstVal, SecondVal, ThirdVal }
and a class for a model...
public class MyModel
{
public List<MyEnum> MyEnums { get; set; }
}
and the POST body is...
MyEnums=&MyEnums=ThirdVal
Currently, after model binding, the MyEnums property will contain...
[0] = FirstVal
[1] = ThirdVal
Is there was a way to tell the model binder to ignore the empty value in the posted data so that MyEnums property could look like the following?
[0] = ThirdVal
You could write a custom model binder for MyModel:
public class MyModelModelBinder : DefaultModelBinder
{
protected override void SetProperty(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor,
object value)
{
if (value is ICollection<MyEnum>)
{
var myEnums = controllerContext.HttpContext.Request[propertyDescriptor.Name];
if (!string.IsNullOrEmpty(myEnums))
{
var tokens = myEnums.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
value = tokens.Select(x => (MyEnum)Enum.Parse(typeof(MyEnum), x)).ToList();
}
}
base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
}
}
which is registered in Application_Start
:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(MyModel), new MyModelModelBinder());
}
UPDATE:
As requested in the comments section here's how to make the previous binder more generic:
protected override void SetProperty(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor,
object value)
{
var collection = value as IList;
if (collection != null && collection.GetType().IsGenericType)
{
var genericArgument = collection
.GetType()
.GetGenericArguments()
.Where(t => t.IsEnum)
.FirstOrDefault();
if (genericArgument != null)
{
collection.Clear();
var enumValues = controllerContext.HttpContext
.Request[propertyDescriptor.Name];
var tokens = enumValues.Split(
new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var token in tokens)
{
collection.Add(Enum.Parse(genericArgument, token));
}
}
}
base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
}
这篇关于有没有办法有绑定到一个List&LT当DefaultModelBinder忽略空项目;枚举&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!