我遇到了自定义模型绑定器的问题。
我有两个模型(继承自基类),由EditorTemplates显示。
基类:
public abstract class QuestionAnswerInputModel {
public Guid QuestionId {
get; set;
}
}
模型类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; }
}
为了让它受到约束,我实现了一个自定义模型绑定器:
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);
}
}
总而言之,它的效果很好,但是没有设置模型的值fpr属性(QuestionId和Rating / Freetext)?谁能告诉我为什么?我做错了什么?
我也试过打电话
new DefaultModelBinder().BindModel(controllerContext, context)
但结果是一样的。未正确实例化对象,但未设置属性。
更新:
我现在尝试覆盖DefaultBinder的CreateModel-Methode,就像在这篇文章MVC 3 Model Binding a Sub Type (Abstract Class or Interface)中一样。
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 :(得分: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!