上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程是什么样的?将在本篇为大家解除这些疑惑,在其中涉及到的一些描述类型和上下文参数会在后续的篇幅中讲到。
IModelBinder、自定义Model绑定器简单实现
Model绑定器在MVC框架中的位置
MVC中的默认Model绑定器生成过程
IModelBinderProvider的简单应用
IValueProvider在MVC框架中生成的位置以及过程
IValueProvider的应用场景
IValueProvider的实现之NameValueCollectionValueProvider
不废话直接进入主题,Model绑定器顾名思义是为了Model的绑定提供帮助的这么一个功能模块,暂且就这么理解。Model这里所指的就是ViewModel,一般都是在控制器方法参数中使用Model,从而使Model绑定器可以使用起来,可是有没有想过为什么要这样用呢?世间的事物都是有因果的,当然这样的使用方式也逃脱不了,这跟MVC框架中生成Model绑定器的位置是有关系的,我们来看示意图1。
图1
看到图1,可能有的朋友可能觉得很突兀,这里建议朋友们先去看一下博主前面所写过的ASP.NET MVC过滤器系列的文章,看过的朋友肯定就会觉得很熟悉了,但也要考虑没有看过前面篇幅的朋友。
ControllerActionInvoker类型的InvokeAction()方法是MVC框架中执行控制器方法的必经方法,我们就按照图1所示的来讲解,***的指示线条为主要流程(虽然不是流程图)。首先MVC会生成一个ControllerDescriptor类型,然后根据ControllerDescriptor类型再生成ActionDescriptor类型,然后再根据ActionDescriptor类型生成FilterInfo类型的对象,对于ControllerDescriptor类型和ActionDescriptor类型分别表示着控制器描述类型(对象内部包含着控制器的各种信息)和控制器方法描述类型(同控制器描述类型一个意思),这两个类型的含义和生成过程后面篇幅会有讲解,这里暂时只需了解它们代表着什么就行。
对于FilterInfo类型的解释是它包含着当前所被调用的控制其方法上的所有过滤器信息(博主还是建议朋友们去看ASP.NET MVC过滤器系列的文章),从它的结构中可以看出它包含着各种类型过滤器类型集合对象属性。
重点来了,从图1中可以看出MVC框架会先执行授权认证IAuthorizationFilter过滤器,在执行完IAuthorizationFilter过滤器后和执行控制器行为过滤器IActionFilter之前,MVC会根据ActionDescriptor类型获取到ParameterDescriptor类型的对象【这里说句题外话看过前面Model元数据的朋友,想必知道ParameterDescriptor类型和Model元数据的都是用来描述Model的,ParameterDescriptor类型重在描述Model本身,而Model元数据更侧重于Model的外部修饰,感叹MVC的强大】。
然后再根据ParameterDescriptor类型中ParameterType属性,表示着Model的类型(Type类型)来生成Model绑定器(IModelBinder),至于生成的细节在下一小节来讲解,不能抢楼下的生意。
想必大家现在知道为什么要把ViewModel放在控制器方法中作为参数来使用了吧。
本小节讲解Model绑定器生成的具体过程,也不是太复杂,并且会在后续篇幅控制器方法执行篇幅会将这些知识点全部串联起来。
现在我们还是先看一下Model绑定器生成的细节吧,图2
图2
(黑体字部分表示为属性名称,黑体字前面的青色表示属性类型,而在黑体字上面的表示属性所属类型)
按照图2所示的来讲解,首先MVC调用了ControllerActionInvoker类型的GetModelBinder ()方法来生成IModelBinder类型,在方法的内部,MVC首先会判断参数parameterDescriptor中的BindingInfo属性中的Binder属性是否为空,如果为空的话(此部分内容在下篇中会详解ParameterDescriptor类型,并且以反推的方法来往上讲解几种描述类型),则是调用ControllerActionInvoker类型中的Binders属性。
现在我们就来看一下Binders属性的定义,如代码1-1。
代码1-1
protected internal ModelBinderDictionary Binders { get { if (this._binders == null) { this._binders = ModelBinders.Binders; } return this._binders; } set { this._binders = value; } }
从代码1-1中可以清楚的看到,对于Binders属性的使用实际是在使用当前系统上下文中的ModelBinders.Binders属性,这里先暂停一下,我们看下ModelBinders.Binders属性中系统给默认提供的绑定器,代码1-2。
代码1-2
private static ModelBinderDictionary CreateDefaultBinderDictionary() { ModelBinderDictionary dictionary2 = new ModelBinderDictionary(); dictionary2.Add(typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder()); dictionary2.Add(typeof(byte[]), new ByteArrayModelBinder()); dictionary2.Add(typeof(Binary), new LinqBinaryModelBinder()); return dictionary2; }
这里没有其它的意思,就是让大家看一下系统默认提供的几种Model绑定器类型,同样是使用ModelBinderDictionary类型的Add()方法,唯一不同的就是这是在系统启动时就会添加生成好的,而我们自定义的Model绑定器则是后面手动添加的。
切回主题,从图2中我们可以看到在ModelBinderDictionary类型调用GetBinder()方法的时候实际是调用的ModelBinderProviderCollection类型的GetBinder()方法,其实在ModelBinderDictionary类型的内部有着一个ModelBinderProviderCollection类型的字段,再看图2,在实际调用ModelBinderProviderCollection类型的GetBinder()方法的时候其实真正调用的是IModelBinderProvider类型中的GetBinder()方法。
然而在反编译工具中也有反编译不了的,好比ModelBinderProviderCollection类型,我就没看到它实例化的细节,不过没关系在下一篇中会证明出来它的内部细节。
本篇内容就讲解到这,后续的篇幅中会讲解如何使用这些类型来实现生成Model绑定器并且进行Model绑定。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。