zoukankan      html  css  js  c++  java
  • 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,所有的形参都是通过它去处理的。

    image

    下面是源码,这里可以看到有两个重要的方法  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...   
                }
            }
        }
  • 相关阅读:
    替换空格
    centos虚拟机 服务器搭建
    Java 深度遍历和广度优先遍历
    idea热部署Devtools
    idea字符编码设置
    idea破解详细教程
    Java序列化
    60+Git常用命令行
    LeetCode 236. 二叉树的最近公共祖先
    08 讲解v-cloak,v-text,v-html的基本使用
  • 原文地址:https://www.cnblogs.com/LiangSW/p/6041074.html
Copyright © 2011-2022 走看看