2010-02-25 2 views
3

DefaultModelBinder가 열거 형 목록에 바인딩되는 방식을 변경하려는 시나리오가 있습니다.List에 바인딩 할 때 DefaultModelBinder가 빈 항목을 무시하도록 할 수 있습니까? <Enum>

내가 열거를

...

public enum MyEnum { FirstVal, SecondVal, ThirdVal } 

및 모델에 대한 클래스 ...

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

과 POST의 몸은 ...

MyEnums=&MyEnums=ThirdVal 

현재 모델 바인딩 후, MyEnums 속성은 다음을 포함합니다 ...

[0] = FirstVal 
[1] = ThirdVal 

MyEnums 속성이 다음과 같이 보이도록 게시 된 데이터의 빈 값을 모델 바인더가 무시하도록 지시하는 방법이 있습니까?

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에 등록 :

[0] = ThirdVal 

답변

6

당신은 MyModel에 대한 사용자 정의 모델 바인더를 작성할 수

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

:

의 요청으로 댓글 se 여기에 이전 바인더를보다 일반적인 것으로 만드는 방법이 있습니다 :

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