ModelBinder:ASP.NET MVC Model绑定的核心

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数。通过前面的介绍我们知道Action方法的参数通过ParameterDescriptor来描述,ParameterDescriptor的BindingInfo属性表示的ParameterBindingInfo对象具有一个名为ModelBinder的组件用于完成针对当前参数的Model绑定。ModelBinder可以看成是整个Model绑定系统的核心,我们先来认识这个重要的组件。

一、 ModelBinder

用于进行Model绑定的ModelBinder对象实现了接口IModelBinder。如下面的代码片断所示,IModelBinder接口具有唯一的BindModel方法用于实现针对某个参数的绑定操作,该方法的返回值表示的就是最终作为参数值的对象。

   1: public interface IModelBinder   2: {   3:     object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);   4: }

IModelBinder的BindModel方法接受两个参数,一个是表示当前的Controller上下文,另一个是表示针对当前Model绑定的上下文,通过类型ModelBindingContext表示。在Controller初始化的时候,Controller上下文已经被创建出来,所以我们只要能够针对当前的Model绑定创建相应的ModelBindingContext,我们就能使用基于某个参数的ModelBinder得到对应的参数值。关于ModelBindingContext的创建我们会在后续部分进行的单独介绍,我们先来介绍一下ModelBinder的提供机制。

二、CustomModelBinderAttribute与ModelBinderAttribute

如果针对某个参数的ParameterDescriptor具有相应的ModelBinder,那么它会被优先选择用于针对该参数的Model绑定,那么ParameterDescriptor的ModelBinder是如何来提供的呢?这是实际上设置一个具有如下定义的CustomModelBinderAttribute特性。抽象类CustomModelBinderAttribute定义了唯一的抽象方法GetBinder用于获取相应的ModelBinder对象。

   1: [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct   2:     | AttributeTargets.Class, AllowMultiple=false, Inherited=false)]   3: public abstract class CustomModelBinderAttribute : Attribute   4: {   5:     public abstract IModelBinder GetBinder();   6: }

在ASP.NET MVC应用编程接口中,CustomModelBinderAttribute具有一个具有如下定义的唯一继承类型ModelBinderAttribute。我们可以通过应用ModelBinderAttribute特性动态地选择用于Model绑定的ModelBinder类型。

   1: [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Interface |   2:     AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class,   3:     AllowMultiple=false, Inherited=false)]   4: public sealed class ModelBinderAttribute : CustomModelBinderAttribute   5: {   6:     public ModelBinderAttribute(Type binderType);   7:     public override IModelBinder GetBinder();   8:    9:     public Type BinderType { [CompilerGenerated] get;  }  10: }

从应用在ModelBinderAttribute类型上的AttributeUsageAttribute定义可以看出该特性不仅仅可以应用在参数上,也可以应用类型(接口、枚举、结构和类)上,这意味我们既可以将它应用在Action方法的某个参数上,也可以将它应用在某个参数的类型上。但是ParameterDescriptor只会解析应用在参数上的特性,所以应用在参数对象类型上的ModelBinderAttribute对它是无效的。

为了演示ModelBinderAttribute特性对ParameterDescriptor的影响,我们来进行一个简单的实例演示。在一个通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中定义了如下几个类型,其中FooModelBinder和BarModelBinder是显现了IModelBinder的自定义ModelBinder类型,而Foo、Bar和Baz是三个将被作为Action方法参数的数据类型,其中Bar上应用了ModelBinderAttribute特性并将ModelBinder类型设置为BarModelBinder。

   1: public class FooModelBinder : IModelBinder   2: {   3:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)   4:     {   5:         throw new NotImplementedException();   6:     }   7: }   8: public class BarModelBinder : IModelBinder   9: {  10:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)  11:     {  12:         throw new NotImplementedException();  13:     }  14: }  15:   16: public class Foo { }  17: [ModelBinder(typeof(BarModelBinder))]  18: public class Bar { }  19: public class Baz { }

然后再创建的默认HomeController中定义如下两个Action方法。DoSomething方法具有三个参数,类型分别是Foo、Bar和Baz,在第一个参数上应用了ModelBinderAttribute特性并将ModelBinder类型设置为FooModelBinder。

   1: public class HomeController : Controller   2: {   3:     public void Index()   4:     {   5:         ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(typeof(HomeController));   6:         ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(ControllerContext, "DoSomething");   7:         IModelBinder foo = actionDescriptor.GetParameters().First(p => p.ParameterName == "foo").BindingInfo.Binder;   8:         IModelBinder bar = actionDescriptor.GetParameters().First(p => p.ParameterName == "bar").BindingInfo.Binder;   9:         IModelBinder baz = actionDescriptor.GetParameters().First(p => p.ParameterName == "baz").BindingInfo.Binder;  10:   11:         Response.Write(string.Format("foo: {0}<br/>", null == foo? "N/A": foo.GetType().Name));  12:         Response.Write(string.Format("bar: {0}<br/>", null == bar ? "N/A" : bar.GetType().Name));  13:         Response.Write(string.Format("baz: {0}<br/>", null == baz ? "N/A" : baz.GetType().Name));  14:     }  15:   16:     public void DoSomething([ModelBinder(typeof(FooModelBinder))]Foo foo,Bar bar, Bar baz)  17:     {}  18: }

在默认的Action方法Index中,我们针对HomeController类型的ReflectedControllerDescriptor对象并获取到用于描述Action方法DoSomething的ActionDescriptor对象。最后我们通过该ActionDescriptor对象得到用于描述其三个参数的ParameterDescriptor对象,并将其ModelBinder类西国内呈现出来。当我们运行该程序的时候,会在浏览器中产生如下的输出结果,可以看出对于分别应用在参数和参数类型上的ModelBinderAttribute特性,只有前者会对ParameterDescriptor的ModelBinder的选择造成影响。

   1: foo: FooModelBinder   2: bar: N/A   3: baz: N/A

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索应用
, 参数
, 方法
, 类型
, public
, model first
, 参数绑定
, class绑定
, 自定义ModelBinder
, 绑定class
Action参数绑定
mvc4 view model 绑定、mvc model 绑定、mvc 自动绑定model、mvc 动态绑定model、mvc中的model,以便于您获取更多的相关知识。

时间: 2024-09-17 04:14:15

ModelBinder:ASP.NET MVC Model绑定的核心的相关文章

ModelBinder——ASP.NET MVC Model绑定的核心

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过ParameterDescriptor来描述,ParameterDescriptor的BindingInfo属性表示的ParameterBindingInfo对象具有一个名为ModelBinder的组件用于完成针对当前参数的Model绑定.ModelBinder可以看成是整个Model绑定系统的核心,我们先来认识这个重要的组件.[本文已经同步到<How ASP.NET

ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProvider

在<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator>中我们介绍了ASP.NET MVC用于Model验证的四种ModelValidator,那么这些ModelValidator是如何被创建的呢?ASP.NET MVC的很多组件(比如ModelBinder和Filter)都采用了基于Provider的提供机制,这篇文章为你讲述这些ModelValidator对应的ModelValidatorProvider. 一.ModelVali

ASP.NET MVC以ModelValidator为核心的Model验证体系:ModelValidatorProviders

前面篇文章我们分别介绍用真正用于实施Model验证的ModelValidator(<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator>),以及用于提供ModelValidator的ModelValidatorProvider(<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProvider>),那么对于ASP.NET MVC的Model验证体系来说,最终是通

ASP.NET MVC以ValueProvider为核心的值提供系统: NameValueCollectionValueProvider

在进行Model绑定过程中,需要根据基于Action方法参数的绑定上下文从请求数据中提取相应的数据以提供相应的数据.具体来说,Model绑定的数据具有多个来源,可能来源于Post的表单或者JSON字符串,或者来源于当前的路由数据,也可能来源于请求地址的插叙字符串.ASP.NET MVC将这种基于不同数据来源的数据获取/提供机制实现在一个叫做ValueProvider的组件中.[本文已经同步到<How ASP.NET MVC Works?>中] 目录 一.IValueProvider与Value

ASP.NET MVC以ValueProvider为核心的值提供系统: ValueProviderFactory

在ASP.NET Model绑定系统中,用于提供数据值的ValueProvider对象通过ValueProviderFactory来创建.在ASP.NET MVC应用编程接口中,ValueProviderFactory继承自ValueProviderFactory类.本篇文章只要介绍基于ValueProviderFactory的ValueProvider的提供机制,以及如何通过自定义ValueProviderFactory实现我们需要的数据值的绑定方式.[本文已经同步到<How ASP.NET

ASP.NET MVC以ValueProvider为核心的值提供系统: DictionaryValueProvider

NameValueCollectionValueProvider采用一个NameValueCollection作为数据源,DictionnaryValueProvider的数据源类型自然就是一个Dictionnary.NameValueCollection和Dictionnary都是一个键值对的集合,它们之间的不同之处在NameValueCollection运行元素具有相同的Key,Dictionnary却要求元素的Key具有唯一性.[本文已经同步到<How ASP.NET MVC Works?

ASP.NET MVC 模型绑定的 6 个建议

原文名称:6 Tips for ASP.NET MVC Model Binding 原文地址:http://odetocode.com/Blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx ASP.NETMVC中的Model Binding使用起来非常简单.你的Action方法需要数据,在传入的HTTP请求中携带着你需要的数据,数据可以在请求的表单数据中,还可能在你的URL地址本身中.通过DefaultM

ASP.NET MVC模型绑定的6个建议,徐汇区网站设计

ASP.NET MVC中的Model Binding使用起来非常简单.你的Action方法需要数据,在传入的HTTP请求中携带着你需要的数据,数据可以在请求的表单数据中,还可能在你的URL地址本身中.通过DefaultModelBinder,可以神奇地将表单中的数据和路由中的数据转换到对象中.Model Binder使得你的控制器代码可以干净地从请求以及关联的环境中分离出来. 这里有一些关于在MVC项目中更好使用Model Binding的建议. Tip#1:最好使用Model Binding而

Asp.Net Mvc: Model Binding to Simple Types, Complex Types,……

Asp.Net Mvc: Model Binding to Simple Types, Complex Types, Collections, Dictionaries, Etc 环境: Windows 2008, VS 2008 SP1, Asp.Net Mvc RC1 1. 简单类型 这里,我们将下面这个Book类称为简单类型: public class Book { public int BookId { get; set; } public string BookName { get;