【问题标题】:ASP.NET MVC ModelBinding Inherited ClassesASP.NET MVC ModelBinding 继承的类
【发布时间】:2009-12-01 23:28:34
【问题描述】:

我有一个关于 ASP.NET MVC(我使用的是 MVC 2 预览版 2)中的 ModelBinding 与继承相关的问题。

假设我有以下接口/类:

interface IBase
class Base : IBase
interface IChild
class Child: Base, IChild

我有一个自定义模型绑定器 BaseModelBinder。

以下工作正常:

ModelBinders.Binders[typeof(Child)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IChild)] = new BaseModelBinder();

以下内容不起作用(在绑定 Child 类型的对象时):

ModelBinders.Binders[typeof(Base)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IBase)] = new BaseModelBinder();

有什么方法可以为基类创建一个模型绑定器,该模型绑定器将应用于所有继承的类?我真的不想为每个可能的继承类手动输入一些东西。

另外,如果可能的话,有没有办法为特定的继承类覆盖模型绑定器?假设我得到了这个工作,但我需要一个用于 Child2 的特定模型绑定器。

提前致谢。

【问题讨论】:

    标签: asp.net-mvc inheritance modelbinders


    【解决方案1】:

    我采取了一条简单的路线,我只是在启动时使用反射动态注册所有派生类。也许这不是一个干净的解决方案,但它只是初始化代码中的几行代码;-)

    但是,如果您真的想弄乱模型活页夹(您将HAVE - 最终 - 但有更好的方式来消磨时间 ;-) 您可以阅读 this 和 @ 987654322@.

    【讨论】:

    • 我会说这是一个更好的解决方案,减少不必要的副作用的风险。
    【解决方案2】:

    好吧,我想一种方法是子类化 ModelBindersDictionary 类并覆盖 GetBinders(Type modelType, bool fallbackToDefault) 方法。

    public class CustomModelBinderDictionary : ModelBinderDictionary
    {
        public override IModelBinder GetBinder(Type modelType, bool fallbackToDefault)
        {
            IModelBinder binder = base.GetBinder(modelType, false);
    
            if (binder == null)
            {
                Type baseType = modelType.BaseType;
                while (binder == null && baseType != typeof(object))
                {
                    binder = base.GetBinder(baseType, false);
                    baseType = baseType.BaseType;
                }
            }
    
            return binder ?? DefaultBinder;
        }
    }
    

    基本上遍历类层次结构,直到找到模型绑定器或默认为DefaultModelBinder

    下一步是让框架接受CustomModelBinderDictionary。据我所知,您需要对以下三个类进行子类化并覆盖 Binders 属性:DefaultModelBinderControllerActionInvokerController。您可能想提供自己的静态 CustomModelBinders 类。

    免责声明:这只是一个粗略的原型。我不确定它是否真的有效,它可能有什么影响,或者它是否是一种合理的方法。您可能想自己下载框架的code 并进行实验。

    更新

    我想另一种解决方案是定义您自己的CustomModelBindingAttribute

    public class BindToBase : CustomModelBinderAttribute
    {
        public override IModelBinder GetBinder()
        {
            return new BaseModelBinder();
        }
    }
    
    public class CustomController
    {
       public ActionResult([BindToBase] Child child)
       {
           // Logic.
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-27
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多