ModelBinder

MVC Form表单的value就会自动匹配到Action的参数中,是如何实现的呢?

通过 反编译System.Web.Mvc.dll, 从Controller入手,会发现Controller中的执行核心ExcuteCore()中会InvokeAction

这里ActionInvoker是一个ControllerActionInvoker对象中调用了GetPrameterValues方法

ActionDescriptor的作用是对Action方法的元数据的描述,通过ActionDescriptor可以获取action的参数列表。

遍历参数列表为参数列表和表单数据做binding。

这里Modelbinder出现了,初始化Modelbinding上下文

ModelMetaData: model的显示和验证信息。

ModelName:model名称,如果有前缀的话就是前缀名(User.Name),没有的话就是参数名(User or Name)

ModelState: 提示model的错误信息,验证通过IsValid = ture

PropertyFilter:ParameterBindingInfo参数绑定的信息,如:有没有前缀,有没有需要include或exclude binding的数据。

关键方法ModelBinder.BindModel.

MVC有默认的ModelBinder:DefaultModelBinder 实现了IModelBinder接口的BindModel方法即可。(所以我们如果想实现自己的ModelBinder,可以实现IModelBinder接口)BindModel中有两种SimpleBind ,ComplexBind

自定义MyModelBinder:

public class MyModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            return GetModel(bindingContext.ValueProvider, bindingContext.ModelName, bindingContext.ModelType);
        }
        public object GetModel(IValueProvider valueProvider, string modelName, Type modelType)
        {

            ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, modelType);
            //如果绑定的类型是简单类型
            if (!modelMetadata.IsComplexType)
            {
                return valueProvider.GetValue(modelName).ConvertTo(modelType);
            }
            object model = Activator.CreateInstance(modelType);
            //如果是复杂类型
            //前台表单标签的name属性的值有modelName的前缀
            if (valueProvider.ContainsPrefix(modelName))
            {
                foreach (PropertyDescriptor porperty in TypeDescriptor.GetProperties(modelType))
                {

                    string strkey = modelName + "." + porperty.Name;
                    if (HttpContext.Current.Request.Form.AllKeys.Contains<string>(strkey))
                        porperty.SetValue(model, valueProvider.GetValue(strkey).ConvertTo(porperty.PropertyType));
                }
            }
            //不包含前缀,但是标签的name属性的值等于绑定类的属性的名字
            else
            {
                foreach (PropertyDescriptor porperty in TypeDescriptor.GetProperties(modelType))
                {
                    string strkey = porperty.Name;
                    if (HttpContext.Current.Request.Form.AllKeys.Contains<string>(strkey))
                        porperty.SetValue(model, valueProvider.GetValue(strkey).ConvertTo(porperty.PropertyType));
                }

            }
            return model;
        }

    }

 public ActionResult ModelBinder([ModelBinder(typeof(MyModelBinder))]User User)
时间: 2024-11-06 22:25:04

ModelBinder的相关文章

MVC5 ModelBinder

MVC5 ModelBinder 什么是ModelBinding ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应.为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinding.ModelBinding的作用就是为Action提供参数列表. ModelBinding的好处 使代码变

modelbinder机制原理

ModelBinder介绍 一.问题描述 当运行一个Mvc时,你控制器中的Action方法需要参数数据:而这些参数数据包含在HTTP请求中,包括表单上的Value和URL中的参数等.但问题是控制器中的Action方法和表单数据是怎么关联的呢? 二.解决方案 微软ModelBinder的功能就是将这些个表单上的Value和URL中的参数换成对象,然后将这些对象绑定到Action的参数上面.如图: 三.下面是一个简单的案例的操作步骤 (一)建立Mvc项目 首先建立一个Mvc应用程序,具体步骤如图:

MVC扩展ModelBinder,通过继承DefaultModelBinder把表单数据封装成类作为action参数

把视图省.市.街道表单数据,封装成一个类,作为action参数.如下: action方法参数类型: namespace MvcApplication1.Models{    public class Customer    {        public string Address { get; set; }    }} 在自定义ModelBinder中,接收视图表单数据,封装成Customer类. using System.Web; using System.Web.Mvc; using M

MVC源码分析 - ModelBinder绑定 / 自定义数据绑定

这几天老感觉不对, 总觉得少点什么, 今天才发现, 前面 3 里面, 在获取Action参数信息的时候,  少解析了. 里面还有一个比较重要的东西. 今天看也是一样的. 在 InvokeAction() 方法里面, 有一句代码: IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor); 这个是用来获取参数的. 那么参数是不是随便获取呢?

ASP.NET MVC5 ModelBinder

什么是ModelBinder ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应.为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinder.ModelBinder的作用就是为Action提供参数列表. ModelBinder的好处 使代码变得更加简洁 帮助我们获取HTTP请求中的数

MVC扩展ModelBinder使类型为DateTime的Action参数可以接收日期格式的字符串

原文:MVC扩展ModelBinder使类型为DateTime的Action参数可以接收日期格式的字符串 如何让视图通过某种途径,把符合日期格式的字符串放到路由中,再传递给类型为DateTime的控制器方法参数?即string→DateTime.MVC默认的ModelBinder并没有提供这样的机制,所以我们要自定义一个ModelBinder. 首先,在前台视图中,把符合日期格式的字符串赋值给date变量放在路由中: @Html.ActionLink("传入日期格式为2014-06-19&quo

MVC学习系列——ModelBinder扩展

在MVC系统中,我们接受数据,运用的是ModelBinder 的技术. MVC学习系列——ActionResult扩展在这个系列中,我们自定义了XmlResult的返回结果. 那么是不是意味着能POST一个XML数据类型给我们项目,这样的话,我们需要自定义一个XmlModelBinder来接受XML数据. 新建XmlModelBinder,继承于:IModelBinder 1 public class XmlModelBinder : IModelBinder 2 { 3 public obje

使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇

jQuery提供的ajax方法能很方便的实现客户端与服务器的异步交互,在asp.net mvc 框架使用jQuery能很方便地异步获取提交数据,给用户提供更好的体验! 调用jQuery的ajax方法时,jQuery会根据post或者get协议对参数data进行序列化; 如果提交的数据使用复杂的json数据,例如: {userId:32323,userName:{firstName:"李",lastName:"李大嘴"}} 那么服务器是无法正常接收到完整的参数,因为j

理解ASP.NET MVC中的ModelBinder

模型绑定的本质 任何控制器方法的执行都受action invoker组件(下文用invoker代替)控制.对于每个Action方法的参数,这个invoker组件都会获取一个Model Binder Object(模型绑定器对象).Model Binder的职责包括为Action方法参数寻找一个可能的值(从HTTP请求上下文).每个参数都可以绑定到不同的Model Binder:但是大部分情况我们都使用的是默认模型绑定器-DefaultModelBinder(如果我们没有显式设置使用自定义的Mod