2011-08-01 1 views
1

나는 추상 클래스에 대한 사용자 지정 바인더를 만들었습니다. 바인더는 사용할 구현을 결정합니다. 잘 작동하지만 추상 클래스에 존재하지 않는 속성을 하위 클래스에 추가하면 항상 null입니다.JSON 사용자 정의 바인더 파생 된 추상 클래스의 null asp.net mvc

다음은 추상 클래스 Pet 및 파생 클래스 DogCat의 코드입니다.

public abstract class Pet 
{ 
    public string name { get; set; } 
    public string species { get; set; } 
    abstract public string talk { get; } 
} 

public class Dog : Pet 
{ 
    override public string talk { get { return "Bark!"; } } 
} 
public class Cat : Pet 
{ 
    override public string talk { get { return "Miaow."; } } 
    public string parasite { get;set; } 
} 


public class DefaultPetBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType) 
    { 
     bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName); 
     string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : ""; 

     // get the parameter species 
     ValueProviderResult result; 
     result = bindingContext.ValueProvider.GetValue(prefix+"species"); 

     if (result.AttemptedValue.Equals("cat")){ 
      //var model = base.CreateModel(controllerContext, bindingContext, typeof(Cat)); 
      return base.CreateModel(controllerContext,bindingContext,typeof(Cat)); 
     } 
     else (result.AttemptedValue.Equals("dog")) 
     { 
      return base.CreateModel(controllerContext,bindingContext,typeof(Dog)); 
     } 
    } 
} 

컨트롤러는 Pet 매개 변수를 사용하여 JSON으로 반환합니다. 내가

{name:"Odie", species:"dog"} 

를 보낼 경우

내가 다시

{"talk":"Bark!","name":"Odie","species":"dog"} 

Cat 얻을, 추상 클래스 Pet에 존재하지 않는 기생충 속성이 있습니다. 내가

{"parasite":"cockroaches","name":"Oggy","species":"cat"} 

를 보낼 경우 나는

내가 다른 더 복잡한 클래스와이 시도했다
{"talk":"Miaow.","parasite":null,"name":"Oggy","species":"cat"} 

, 이것은 단순한 예입니다 다시 얻을. 디버거를 보았습니다. parasite 값이 값 공급자에 있습니다. 바인더가 반환하는 모델에는 기생충 필드가 있습니다. 누구든지 문제가있는 곳을 볼 수 있습니까?

답변

5

는 다음과 같이하십시오 : 완벽하게 작동

protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType) 
{ 
    bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName); 
    string prefix = ((hasPrefix)&&(bindingContext.ModelName!="")) ? bindingContext.ModelName + "." : ""; 

    // get the parameter species 
    ValueProviderResult result; 
    result = bindingContext.ValueProvider.GetValue(prefix+"species"); 

    if (result.AttemptedValue.Equals("cat")) 
    { 
     var model = Activator.CreateInstance(typeof(Cat)); 
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Cat)); 
     return model; 
    } 
    else if (result.AttemptedValue.Equals("dog")) 
    { 
     var model = Activator.CreateInstance(typeof(Dog)); 
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(Dog)); 
     return model; 
    } 

    throw new Exception(string.Format("Unknown type \"{0}\"", result.AttemptedValue)); 
} 
+0

감사합니다. – semaz

관련 문제