2010-02-25 1 views
3

У меня есть сценарий, в котором я хотел бы изменить поведение DefaultModelBinder в том, как он привязывается к списку перечислений.Есть ли способ, чтобы DefaultModelBinder игнорировал пустые элементы при привязке к списку <Enum>

У меня есть перечисление ...

public enum MyEnum { FirstVal, SecondVal, ThirdVal } 

и класс для модели ...

public class MyModel 
{ 
    public List<MyEnum> MyEnums { get; set; } 
} 

и тело СТОЛБ ...

MyEnums=&MyEnums=ThirdVal 

В настоящее время , после привязки к модели, свойство MyEnums будет содержать ...

[0] = FirstVal 
[1] = ThirdVal 

Был ли способ сообщить связующемуся модели игнорировать пустое значение в опубликованных данных, чтобы свойство MyEnums выглядело следующим образом?

[0] = ThirdVal 

ответ

6

Вы можете написать собственную модель связующие для 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); 
    } 
} 

, который зарегистрирован в Application_Start:

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    ModelBinders.Binders.Add(typeof(MyModel), new MyModelModelBinder()); 
} 

UPDATE:

В соответствии с просьбой в комментарии se ction здесь, как сделать предыдущее связующее более общим:

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); 
} 
+0

Мне это нравится, спасибо. Вы знаете, как это можно сделать для работы любого типа Enum? – JeremyWeir

+0

Да, см. Мое обновление. –

+0

Ничего себе, отлично работал, спасибо. – JeremyWeir

 Смежные вопросы

  • Нет связанных вопросов^_^