【问题标题】:ASP.NET: Modelbinder only delegatingASP.NET:Modelbinder 仅委托
【发布时间】:2014-11-27 11:36:36
【问题描述】:

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

我有两个由 EditorTemplates 显示的模型(继承自基类)。

基类:

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

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

【问题讨论】:

  • 您的操作期望的模型类型是什么?它是基础抽象类吗?
  • 是的,ActionMethode 想要一个具有 IList 类型属性的模型!
  • 是的,我做到了。但这意味着我必须自己解决所有属性,在这种情况下这不是什么大问题。但是对于更复杂的模型,这真的很烦人。我只是想知道为什么默认的modelbinder无法解析属性?
  • 但是您是否尝试过 Manas 提出的解决方案(2. 现在创建一个模型绑定器并覆盖 CreateModel)?

标签: c# asp.net asp.net-mvc model-binding custom-model-binder


【解决方案1】:

在与@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!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多