MVC5-10 ModleBinder那点事

模型绑定器

之前或多或少也提到过模型绑定器,方法的形参就是由模型绑定器把参数绑定上去的,今天就说说ModuleBingder那点事

在MVC中有一个接口叫IModuleBinder

//
    // 摘要:
    //     Defines the method that is required for a model binder.
    public interface IModelBinder
    {
        //
        // 摘要:
        //     Binds the model to a value by using the specified execution context and binding
        //     context.
        //
        // 参数:
        //   modelBindingExecutionContext:
        //     The execution context.
        //
        //   bindingContext:
        //     The binding context.
        //
        // 返回结果:
        //     true if model binding is successful; otherwise, false.
        bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext);
    }

当然,这是接口,是没有实现的,MVC给我们提供了相应的实现类。DefaultModelBinder,所有的形参都是通过它去处理的。

下面是源码,这里可以看到有两个重要的方法  BindSimpleModel、BindComplexModel 简单类型绑定与复杂类型的绑定,实际上方法是递归调用的,如果参数是对象的话,那就会创建一个对象,然后在绑定每一个属性,而绑定每一个属性的方法里又调用了BindModel方法。

public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            RuntimeHelpers.EnsureSufficientExecutionStack();
            if (bindingContext == null)
            {
                throw new ArgumentNullException("bindingContext");
            }
            bool flag = false;
            if (!string.IsNullOrEmpty(bindingContext.ModelName) && !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
            {
                if (!bindingContext.FallbackToEmptyPrefix)
                {
                    return null;
                }
                ModelBindingContext context = new ModelBindingContext {
                    ModelMetadata = bindingContext.ModelMetadata,
                    ModelState = bindingContext.ModelState,
                    PropertyFilter = bindingContext.PropertyFilter,
                    ValueProvider = bindingContext.ValueProvider
                };
                bindingContext = context;
                flag = true;
            }
            if (!flag)
            {
                bool flag2 = ShouldPerformRequestValidation(controllerContext, bindingContext);
                ValueProviderResult valueProviderResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, !flag2);
                if (valueProviderResult != null)
                {
                    return this.BindSimpleModel(controllerContext, bindingContext, valueProviderResult);
                }
            }
            if (!bindingContext.ModelMetadata.IsComplexType)
            {
                return null;
            }
            return this.BindComplexModel(controllerContext, bindingContext);
        }
protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            object objA = propertyBinder.BindModel(controllerContext, bindingContext);
            if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && object.Equals(objA, string.Empty))
            {
                return null;
            }
            return objA;
        }

MVC是高度可替换的,如果DefaultModelBinder无法很好的实现我们的需求,那么可以写自己的ModelBinder。首先定义一个类去继承自IModelBinder实现BindModel方法,然后在Global里替换我们的MyModelBinder

public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            //替换
            ModelBinders.Binders.DefaultBinder = new MyModelBinder();
        }

        public class MyModelBinder : IModelBinder
        {
            public object BindModel(ModelBindingExecutionContext modelBindingExecutionContext, ModelBindingContext bindingContext)
            {
                //Todo...
            }
        }
    }
时间: 2024-12-15 14:29:08

MVC5-10 ModleBinder那点事的相关文章

<13>【了解】计算机中的进制+【理解】原码反码补码基本概念+【理解】为什么要引入反码、补码?+【掌握】位运算符介绍及使用+位运算应用:编程实现10进制转2进制

1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) { 4 5 //定义10进制数,打印出10.8.16进制的值 6 int a = 13; 7 printf("%d\n",a); 8 printf("%o\n",a); 9 printf("%x\n",a); 10 11 //int 64 4个字节 12 int b = 0b0000000000000000

Java实战之01Struts2-04拦截器、上传下载、OGNL表达式

十二.Struts2中的拦截器 1.拦截器的重要性 Struts2中的很多功能都是由拦截器完成的.比如:servletConfig,staticParam,params,modelDriven等等. 是AOP编程思想的一种应用形式. 2.拦截器的执行时机: \ 3.自定义拦截器 3.1.拦截器的类试图(初级版本): 3.2.编写步骤: a.编写一个类,继承AbstractInterceptor类或者实现Interceptor接口.重写intercept方法. 1 public class MyI

连载《一个程序猿的生命周期》-20.7年工作感悟

百木-ITer职业交流 群-北京 :141588103 工作7年,就其工作中学习到的技术和业务是很有限的,业余的大部分时间还是以自己看书为主,学习到的技术不一定能用的上,但是可以作为知识的储备.除了专业书籍外,也尽量多的看一些其他的书籍,例如:历史.经济.管理等方面的,为了将来有全面的发展储备知识,也是为了激发自己的思考,解构现实世界. 我是比较善于观察和思考的人,人与人之间思考结果的偏差是很大的,造成这样的情况是信息不对称造成的,所以我们要观察.看书.实践.思考......再观察.看书.实践.

管理学定律四:手表定律与破窗理论

1.手表定律 1.1 来源 手表定律是指一个人有一只表时,可以知道现在是几点钟,而当他同时拥有两只表时却无法确定.两只表并不能告诉一个人更准确的时间,反而会使看表的人失去对准确时间的信心.它的提出者是英国心理学家p.萨盖,因此手表定律也叫萨盖定律. 森林里生活着一群猴子,每天太阳升起的时候它们外出觅食,太阳落山的时候回去休息,日子过得平淡而幸福. 一名游客穿越森林,把手表落在了树下的岩石上,被猴子"猛可"拾到了.聪明的"猛可"很快就搞清了手表的用途,于是,"

InnoDB 存储引擎的锁机制

行级别的 - Share and Exclusive Locks 共享锁 S:允许持有S锁的事务对行进行读操作 排他锁 X: 允许持有X锁的事务对行进行update或delete操作 表级别的意向锁 - Intention Lock InnoDB支持多粒度的锁定,允许行锁和表锁共存.通过意向锁来实现. 比如,SELECT ... LOCK IN SHARE MODE sets an IS lock and SELECT ... FOR UPDATE sets an IX lock. 意向共享锁(

据说印度有望推动我国工程机械行业发展?

据说印度有望推动我国工程机械行业发展?机械手夹具在印度公布的“十二五”经济计划(2012-2016年)中,仅将来五年印度的基础设施建造出资金额估计到达1万亿美元,机械手吸盘座出资领域包括公路.铁路.城市基础设施.商业和住宅修建.港口.电力.水利设施.采矿.石油.天然气和机场等.在2012-2030年之间,印度至少将GDP的10%投入到基础设施建造上. 从2007-2015年,印度投放到工程机械手机械市场的资金累计到达400亿美元.机械手配件生产厂家这意味着将来的8年,每年约增加17%的出资额.一

Linux 小知识翻译 - 「为什么安全是互联网的问题?」

当然,虽说「由于有心怀不轨的人在,一定要注意安全问题」.但另一方面,也有人认为「如果互联网自己就考虑好安全问题的话,那么用户就不用再担心安全问题了」. 虽然经常有人这样说「与远程机器通信的时候,避免使用明码传输数据的telnet,而是使用加密传输数据的SSH」,但也有人认为,通信本身这种容易被窃听的机制才是问题所在. 这得从互联网诞生的秘密说起了.互联网的前身被称为「ARPANET」,是以美国国防部为中心研究的,用于军事上的通信网络. 这个网络仅仅是以研究为目的,非常有限的一些人在使用,本来就不

c/c++指针精讲和需要注意的地方

int *x =&10;//不能对10取地址 因为他不在 堆栈区 //堆栈常量区的都b可以对变量取地址 10就是一个字面量 不能取地址 1:指针是一种数据类型 1)指针也是一种变量,占有内存空间,用来保持内存地址,在一般情况下所有指针. 都是4个字节; 2)*p操作内存 再指针声明时,*号表示所声明的变量为指针, 在指针使用时,*号表示操作指针所指向的内存空间的值, *p相当于通过地址{p变量的值}找到一块内存,然后操作内存 *p放在等号左边赋值(给内存赋值) *p放在等号的右边取值(从内存获取

一个程序猿的生命周期

工作7年,就其工作中学习到的技术和业务是很有限的,业余的大部分时间还是以自己看书为主,学习到的技术不一定能用的上,但是可以作为知识的储备.除了专业书籍外,也尽量多的看一些其他的书籍,例如:历史.经济.管理等方面的,为了将来有全面的发展储备知识,也是为了激发自己的思考,解构现实世界. 我是比较善于观察和思考的人,人与人之间思考结果的偏差是很大的,造成这样的情况是信息不对称造成的,所以我们要观察.看书.实践.思考......再观察.看书.实践.思考,最终要完善自己的价值体系.理论体系或是方法体系,这