2014-11-03 2 views
2

다형성 객체 컬렉션을 사용하여 복잡한 모델에 대한 사용자 정의 모델 바인더를 작성할 수 있습니까? 다형성 객체 컬렉션이있는 복잡한 모델 용 사용자 정의 모델 바인더

나는 모델의 다음 구조를 가지고 :

public class CustomAttributeValueViewModel 
{ 
    public int? CustomAttributeValueId { get; set; } 
    public int CustomAttributeId { get; set; } 
    public int EntityId { get; set; } 
    public CustomisableTypes EntityType { get; set; } 
    public string AttributeClassType { get; set; } 
} 

public class CustomStringViewModel : CustomAttributeValueViewModel 
{ 
    public string Value { get; set; } 
} 

public class CustomIntegerViewModel : CustomAttributeValueViewModel 
{ 
    public int Value { get; set; } 
} 

을 그리고 나는 그것의 상속인의 일부 CustomAttributeValueViewModel을 결합 할 경우, 나는 그런 사용자 정의 모델 바인더 사용

public class CustomAttributeValueModelBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(
     ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     Type modelType) 
    { 
     if (modelType == typeof(CustomAttributeValueViewModel)) 
     { 
      var attributeClassType = (string)bindingContext.ValueProvider 
       .GetValue("AttributeClassType") 
       .ConvertTo(typeof(string)); 

      Assembly assembly = typeof(CustomAttributeValueViewModel).Assembly; 
      Type instantiationType = assembly.GetType(attributeClassType, true); 

      var obj = Activator.CreateInstance(instantiationType); 
      bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, instantiationType); 
      bindingContext.ModelMetadata.Model = obj; 
      return obj; 
     } 

     return base.CreateModel(controllerContext, bindingContext, modelType); 
    } 
} 

그것은 잘 작동합니다. 그러나 이제는 다른 모델의 수집 항목과 같은 모델을 바인딩하려고합니다. 예 :

public class SomeEntity 
{ 
    // different properties here 

    public IList<CustomAttributeValueViewModel> CustomAttributes { get; set; } 
} 

어떻게하면됩니까?

편집 :

은 내가 클라이언트로부터받은 게시 된 데이터를 바인딩 할. 더 명확하게하기 위해 내 POST의 HTTP 요청의 예입니다

POST someUrl HTTP/1.1 
User-Agent: Fiddler 
Host: localhost 
Content-Type: application/json; charset=utf-8 
Content-Length: 115 

{ 
    "ProductName": "Product Name", 
    "CustomAttributeValues": [ 
    { 
     "CustomAttributeId": "1", 
     "Value": "123", 
     "AttributeClassType": "namespace.CustomStringViewModel" 
    } 
    ] 
} 

그리고 난 내 행동이 데이터를 수신 : 나는 상속인의 수집을 얻기를 위해 이러한 바인더를 작성하려는

public void Save([ModelBinder(typeof(SomeBinder))] SomeEntity model) 
{ 
    // some logic 
} 

. .`일;

+0

하지 않습니다'새 SomeEntity() CustomAttributes.Add (myModel)에서 봐 주시기 바랍니다는 AttributeClassType에 전체 경로를 포함해야합니까? –

+0

@AndreiV, 나는 당신이 내가 의미하는 것을 이해하지 못했을 것 같아요. 내 행동에 SomeEntity를 바인딩하고 싶습니다. – Neshta

+0

아니요, 아닙니다. 좀 더 명확히 해 주시겠습니까? –

답변

3

당신은

var valueProviderResult = bindingContext.ValueProvider 
          .GetValue(bindingContext.ModelName + ".AttributeClassType"); 

working Github sample

+0

우수! 가이, 너는 내 하루를 만들었 어! – Neshta