C# ASP.NET:仅Modelbinder委派
我面临一个定制modelbinder的问题 我有两个模型继承自EditorTemplates显示的基类 基类:C# ASP.NET:仅Modelbinder委派,c#,asp.net,asp.net-mvc,model-binding,custom-model-binder,C#,Asp.net,Asp.net Mvc,Model Binding,Custom Model Binder,我面临一个定制modelbinder的问题 我有两个模型继承自EditorTemplates显示的基类 基类: public abstract class QuestionAnswerInputModel { public Guid QuestionId { get; set; } } 模型类别1: public class RatingQuestionInputModel : QuestionAnswerInputModel{ [Required]
public abstract class QuestionAnswerInputModel {
public Guid QuestionId {
get; set;
}
}
模型类别1:
public class RatingQuestionInputModel : QuestionAnswerInputModel{
[Required]
[Range(1,4)]
public int? Rating { get; set; }
}
模型类别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);
}
}
总而言之,它工作得很好,但是模型QuestionId和Rating/Freetext的fpr属性值没有设置?谁能告诉我为什么?我做错了什么
我也试着打电话
new DefaultModelBinder().BindModel(controllerContext, context)
但结果是一样的。已正确实例化对象,但未设置属性
更新:
我现在试图覆盖DefaultBinder的CreateModel方法,就像在本文中一样
模型仍然正确实例化。现在的问题是,只设置基类的属性。在与@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方法。感谢@MacPak 你的行动期望什么样的模式?是的,ActionMethode需要一个具有IList类型属性的模型!你看到了吗?是的,我看到了。但这意味着我必须自己解决所有属性,在这种情况下,这不是什么大问题。但对于更复杂的车型来说,这真的很烦人。我只是想知道为什么默认的modelbinder无法解析属性?但您尝试过Manas 2提出的解决方案吗。现在创建modelbinder并覆盖CreateModel?
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;
}