IModelBinder 是MVC中用来解析Request.Form,Requet.Querystring,Request.Files,并将其转换为强类型的实体类的工具类。你在Action上看到的强类型参数就是它对客户端发过来的字符串解析后的结果。
这个功能是ASP.NET MVC的一个非常能够改进开发人员效率的创新性措施。深刻理解、掌握并记住它的内部原理,是做MVC开发架构的基础。
MVC3中提供IModelBinder的是ModelBinders.Binders,你按F12查看其定义,可以看见它是ModelBinderDictionary,查找IModelBinderDictionary就是从它开始的。
ModelBinders.Binders: 跟据当前执行的Action某个参数(的ParameterDescriptor)获取该参数关联的的绑定器IModelBinder,
然后使用该绑定器的BindModel方法,根据客户端传过来的QueryString,Form,RoutData,Files,ChildAction值集合(由ValueProvider提供)的每个key,
根据key查找对应的value,使用这个value来实例化该参数。
(记住:这个参数有可能是一个属性或是一个类。MVC会将Students[0].Name解析为一个长度为1 的Student数组。)
ModelBinders.Binders是主要的类,它在Controller类,ControllerActioinInvoker类和DefaultModelBinder类中都是作为一个属性成员,都定义为ModelBinderDictionary Binders { get { return ModelBinders.Binders; } }
取一个方法参数的值:
第一步:获取该参数对应的IModelBinder.
1、首先会去得到这个参数的PrameterDescriptor(在ActionDescriptor中获取), 访问PrameterDescriptor.BindingInfo.Binder可以得到 参数自定义标识属性(通过ModelBinders.GetBinderFromAttributes(ParameterInfo,string)方法)中所含的IModelBinder
2、如果没有,则根据该参数的类型到ModelBinders.Binders中调用ModelBinderDictionary.GetBinder来获取到参数对应的一个IModelBinder,在这个GetBinder里面,首先会从ModelBinderProviders中查找,如果找到,调用ModelBinderProviderCollection.GetBinder获取到一个IModelBinder,或者具体一点,ModelBinderProviders.BinderProviders[0].GetBinder()
如果仍没找到,就从ModelBinders.Binders自己内部的一个_innerDictionary中查找(这个_innerDictionary可以通过ModelBinders.Binders.Add()来添加自己自定义的。)
如果仍没找到,就从这个参数类型上的标识属性(通过ModelBinders.GetBinderFromAttributes(Type,string)方法)中查找是否有CustomModelBinderAttribute,如果有,调用它的GetBinder来获取到一个IModelBinder
如果还是没找到,就直接使用DefaultModelBinder这个系统默认类
第二部:调用IModelBinder.BindModel() 获取参数的值,如果这个值为空,返回调用ParameterInfoUtil.TryGetDefaultValue获取该类型的一个默认值
DefaultModelBinder是里面核心的绑定类,因为大多的类型,都是它来绑定。