2014-11-27 3 views
0

사용자 지정 모델 결합기에 문제가 있습니다.ASP.NET : 모델 바인더 전용 위임

EditorTemplates에 의해 표시되는 두 개의 모델 (기본 클래스에서 상속)이 있습니다.

자료 클래스 :

public abstract class QuestionAnswerInputModel { 
    public Guid QuestionId { 
     get; set; 
    } 
} 

Modelclass 1 :

public class RatingQuestionInputModel : QuestionAnswerInputModel{ 
    [Required] 
    [Range(1,4)] 
    public int? Rating { get; set; } 
} 

Modelclass 2 :

public class FreeTextQuestionInputModel: QuestionAnswerInputModel{ 
    [Required] 
    public string FreeText { get; set; } 
} 

그것이 내가 정의 ModelBinder를 구현 바인딩으로 활용하려면 다음

public class QuestionAnswerModelBinder : DefaultModelBinder { 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 

     QuestionAnswerInputModel model; 

     if ((typeof(QuestionAnswerInputModel) != bindingContext.ModelType)) { 
      return null; 
     } 

     ModelBindingContext context = new ModelBindingContext(bindingContext); 

     Type typeOfModel; 

     string prefix = bindingContext.ModelName; 
     if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new FreeTextQuestionInputModel().GetPropertyName(m => m.FreeText))) { 
      typeOfModel = typeof(FreeTextQuestionInputModel); 
     } else if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new RatingQuestionInputModel().GetPropertyName(m => m.Rating))) { 
      typeOfModel = typeof(RatingQuestionInputModel); 
     } else { 
      return null; 
     } 

     context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(), bindingContext.ModelMetadata.ContainerType, null, typeOfModel, bindingContext.ModelName); 
     return base.BindModel(controllerContext, context); 
    } 
} 
,536을

모두 멋지지만 모델의 fpr 속성 (QuestionId 및 Rating/Freetext)이 설정되지 않았습니까? 아무도 그 이유를 말할 수 있습니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

는 또한

new DefaultModelBinder().BindModel(controllerContext, context) 

전화를 시도했지만 결과는 동일합니다. 올바르게 인스턴스화 된 객체이지만 속성은 설정되지 않습니다.


업데이트 :

는 지금이 게시물 MVC 3 Model Binding a Sub Type (Abstract Class or Interface)에서 같은 DefaultBinder 단지 CreateModel - 메도을 무시하려고 노력했다.

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { 

     if ((typeof(QuestionAnswerInputModel) != bindingContext.ModelType)) { 
      return null; 
     } 

     string prefix = bindingContext.ModelName; 
     if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new FreeTextQuestionInputModel().GetPropertyName(m => m.FreeText))) { 
      return new FreeTextQuestionInputModel(); 
     } else if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new RatingQuestionInputModel().GetPropertyName(m => m.Rating))) { 
      return new RatingQuestionInputModel(); 
     } else { 
      return null; 
     } 
    } 

모델은 여전히 ​​올바르게 인스턴스화됩니다. 이제 문제는 기본 클래스의 속성 만 설정된다는 것입니다.

+0

귀하의 행동이 예상하는 모델 유형은 무엇입니까? 기본 추상 클래스입니까? – macpak

+0

예 ActionMethode는 IList 유형의 속성을 가진 모델을 원합니다! – Tobias

+0

본 적이 있습니까? http://stackoverflow.com/questions/9417888/mvc-3-model-binding-a-sub-type-abstract-class-or-interface? – macpak

답변

0

@macpak과 논의한 후에 해결책을 찾았습니다. 이것은 나를 위해 잘 작동합니다 :

protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { 

    if ((typeof(QuestionAnswerInputModel) != bindingContext.ModelType)) { 
     return null; 
    } 

    string prefix = bindingContext.ModelName; 

    QuestionAnswerInputModel obj; 
    if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new FreeTextQuestionInputModel().GetPropertyName(m => m.FreeText))) { 
     obj = new FreeTextQuestionInputModel(); 
    } else if (bindingContext.ValueProvider.ContainsPrefix(prefix + "." + new RatingQuestionInputModel().GetPropertyName(m => m.Rating))) { 
     obj = new RatingQuestionInputModel(); 
    } else { 
     return null; 
    } 

    bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, obj.GetType()); 
    bindingContext.ModelMetadata.Model = obj; 

    return obj; 
} 

CreateModel-Methode를 무시하면됩니다. @MacPak에 감사드립니다!