ASP.NET:模型绑定器仅委派

本文关键字:委派 绑定 模型 NET ASP | 更新日期: 2023-09-27 18:32:10

我在自定义模型绑定器中遇到了问题。

我有两个模型(继承自基类),由编辑器模板显示。

基类:

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; }
}

为了绑定它,我实现了一个自定义模型绑定器:

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和评级/自由文本)没有设置?谁能告诉我为什么?我做错了什么?

我也试着打电话

new DefaultModelBinder().BindModel(controllerContext, context)

但结果是一样的。正确实例化的对象,但未设置属性。


更新:

我现在尝试只覆盖 DefaultBinder 的 CreateModel-Methode,就像这篇文章 MVC 3 模型绑定子类型(抽象类或接口)一样。

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;
        }
    }

模型仍正确实例化。现在的问题是,只设置基类的属性。

ASP.NET:模型绑定器仅委派

经过与@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!