ASP.NET MVC Model绑定(二)

ASP.NET MVC Model绑定(二)

前言

上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候运行的?又或是运行的过程是什么样的?将在本篇为大家解除这些疑惑,在当中涉及到的一些描写叙述类型和上下文參数会在兴许的篇幅中讲到。

 

Model绑定

  • IModelBinder、自己定义Model绑定器简单实现
  • Model绑定器在MVC框架中的位置
  • MVC中的默认Model绑定器生成过程
  • IModelBinderProvider的简单应用
  • IValueProvider在MVC框架中生成的位置以及过程
  • IValueProvider的应用场景
  • IValueProvider的实现之NameValueCollectionValueProvider

 

Model绑定器在MVC框架中的位置

不废话直接进入主题,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放在控制器方法中作为參数来使用了吧。

 

MVC中的默认Model绑定器生成过程

本小节解说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绑定。


作者:金源

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。