ASP.NET MVC Model元数据(三)
ASP.NET MVC Model元数据(三)
前言
在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会对Model元数据本身的结构稍作讲解,读完本篇过后你将会对Model元数据的结构有个很清晰的印象。
Model元数据
- 什么是Model元数据?
- 生成Model元数据的过程【一】
- 生成Model元数据的过程【二】
- ModelMetaData的定义、详解
- Model元数据应用(常用特性应用)-1
- Model元数据应用(自定义视图模板)-2
- Model元数据应用(IMetadataAware接口使用)-3
生成Model元数据的过程【二】
还记得Model元数据系列篇的第一章里的最后一幅图吗?
图1

没有错,MVC框架根据我们定义的视图模型生成了一个Model元数据ModelMetadata(实际为DataAnnotationsModelMetadata类型是继承自ModelMetadata类型的,在下文中为了更直观的方便讲解所以还是用ModelMetadata类型来作介绍)。我们来看一下ModelMetadata类型的定义:
代码1-1
public class ModelMetadata
{ public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
//
// 摘要:
// 获取模型元数据对象的集合,这些对象描述模型的属性。
//
// 返回结果:
// 用于描述模型属性的模型元数据对象的集合。
public virtual IEnumerable<ModelMetadata> Properties { get; }
//
// 摘要:
// 获取模型的类型。
//
// 返回结果:
// 模型的类型。
public Type ModelType { get; }
protected ModelMetadataProvider Provider { get; set; }
……
}
只留了个构造函数和三个属性,详细的部分下篇会讲到,构造函数中的第一个参数类型大家肯定很熟悉,那就是上篇中讲到的Model元数据生成程序,用来生成Model元数据(ModelMetadata类型)的,这样的是把ModelMetadataProvider类型的引用设置到Model元数据的内部,也就是Provider属性,这样做是有目的的随后就会讲到,在其定义中还有个Properties属性,类型大家都看到了是ModelMetadata类型的集合,这就是ModelMetadata类型关键的所在了,Properties属性表示着当前ModelMetadata的所描述类型中的属性元数据集合。
图2

用前篇介绍过的Customer类型来做描述,对应着Customer类型的结构MVC框架也会生成对应的ModelMetadata类型结构,这里捎带提一下,对于Address属性类型是Address类型这种属于复杂类型,MVC框架会向下继续生成就如同生成Customer类型一样。
那么这样的结构是怎么生成的呢?当然不用说了,是依靠Provider属性也就是ModelMetadataProvider类型的引用来生成结构的,如图3所示:
图3

首先根据当前Model元数据ModelMetadata类型(对应的对象是Customer类型)中的Model属性和ModelType属性来作为参数调用AssociatedMetadataProvider类型的GetMetadataForProperties()方法,这里说一下ModelMetadata类型的Model属性,表示着当前Model元数据所对应对象的值,也是用这个值来判断是否是复杂类型的,ModelType属性上面说过。
在GetMetadataForProperties()方法中会先根据自定义类型描述类型的GetProperties()方法来获取当前对象是Customer类型的所有的属性,并且封装成属性描述类型集合。
随后根据获取到的属性描述类型集合,遍历此集合并且根据遍历中的单个属性描述类型调用AssociatedMetadataProvider类型中的GetMetadataForProperty()方法,这里要说的是第一个参数modelAccessor默认是Null的,第二个参数containerType是表示着当前Customer类型,第三个参数就是属性描述类型了里面包含着属性类型的所有信息。有的朋友会问说明这些属性做什么,因为等下会说到第二个参数containerType的。
在AssociatedMetadataProvider类型中的GetMetadataForProperty()方法中,会根据PropertyDescriptor类型的参数获取到当前属性上所有描述信息(也就是那些特性类),比如当前的PropertyDescriptor类型是结构化Customer类型中的CustomerID,那图3中AttrbuteList类型中就是包含着所有依附在这个属性上的特性类。后续的生成过程还是跟上篇的讲解的一样依旧的调用了AssociatedMetadataProvider类型的CreateMetadata(),只不过在AssociatedMetadataProvider类型中方法是抽象中,实际是由它的实现类DataAnnotationsModelMetadataProvider中的CreateMetadata()方法来完成的。
这里大家可能会发现,在图3中黄色框中的操作都是属于遍历中的操作,就是每次都会只会生成一个ModelMetadata类型实例然后最后合并在一起返回出去。
还有要说的就是在图3中黄色框中的每个调用的函数都有个Type类型的containerType参数,这就是上面说过的Customer类型,并且在生成的ModelMetadata类型实例中赋值到ContainerType属性,表示着新生成的ModelMetadata类型实例比如叫A,A中描述的信息就是Customer类型中的CustomerID属性的所有信息,而A中的ContainerType属性就是表示描述的CustomerID属性是属于哪个类型的。
这里还有要说的,就是在系统默认生成的时候,比如说视图模型是Customer类型,那么MVC框架只会生成一个ModelMetadata类型的实例假使它叫M,因为M自身并没有自己检测自己是不是复杂类型,所以M是不会调用提供器往下生成的,而是在外部要使用M了才会去调用M中的函数检测M是不是复杂类型然后往下生成,假使现在MVC框架中使用到了这个M可能就会调用检测它自身的方法来检查它是不是复杂类型,明显的Customer类型是复杂类型,这个时候M会按照本篇描述的那样依次的生成它所描述类型中的属性,也只是仅限于这一层,有的朋友可能会问在Customer类型中Address属性也是复杂类型,对的,但是M只会去生成Address属性本身的ModelMetadata类型的实例,而不会去生成Address属性的内部。
现在大家再看一次图2,是不是有点清晰的感觉。
(有哪位大神知道在MVC框架中是在哪里调用ModelMetadata类型实例的自身检测的?知道的告知一下小弟以身相许,找的头破血流也没找到,我相信是肯定有的)
本篇结束,下篇中详细介绍DataAnnotationsModelMetadataProvider类型中的CreateMetadata()方法,从这个方法进入,详细的讲解ModelMetadata对象类型。
作者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
ASP.NET MVC Model元数据(三)的更多相关文章
- ASP.NET MVC Model元数据
ASP.NET MVC Model元数据(三) 前言 在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...
- ASP.NET MVC Model元数据(二)
ASP.NET MVC Model元数据(二) 前言 在上篇中,给大家留个对Model元数据的印象,并没有对Model元数据有过多的讲解,而在本篇中也不会对Model元数据的本身来解释,而是针对于它的 ...
- ASP.NET MVC Model验证(三)
ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...
- ASP.NET MVC Model绑定(三)
ASP.NET MVC Model绑定(三) 前言 看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Mod ...
- ASP.NET MVC Model元数据(五)
ASP.NET MVC Model元数据(五) 前言 在上一篇中我们描述了应用于Model上面的各种用于显示控制的特性类,在本篇中将详细的介绍这些特性类的应用,虽然它们跟Model元数据的直接关系并不 ...
- ASP.NET MVC Model元数据(四)
ASP.NET MVC Model元数据(四) 前言 前面的篇幅讲解了Model元数据生成的过程,并没有对Model元数据生成过程的内部和Model元数据结构的详细解释.看完本篇后将会对Model元数 ...
- ASP.NET MVC Model元数据(一)
ASP.NET MVC Model元数据(一) 前言 在我初学的时候对Model元数据的概念很模糊,或者说是在大脑中没有它的一个模型,作为小白的我去看网上的一些文章还是两眼一黑啥都看不明白,然后我想退 ...
- 【笔记】ASP.NET MVC Model元数据
问题1:什么叫Model元数据? Model元数据,是针对数据类型的一种描述信息.由于复杂类型(或者说类型嵌套的存在,比如CustomerModel中有一个属性为复杂类型Address)的存在,因此M ...
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...
随机推荐
- JS核心系列:浅谈原型对象和原型链
在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象(Object)和函数对象(Function). 一般而言,通过new Function产生的对象是函数对象,其他对 ...
- 对Castle Windsor的Resolve方法的解析时new对象的探讨
依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...
- 【原】AFNetworking源码阅读(一)
[原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...
- 前端学HTTP之web攻击技术
前面的话 简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象.应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标.本文将详细介绍攻击web站点 ...
- Android数据加密之Base64编码算法
前言: 前面学习总结了平时开发中遇见的各种数据加密方式,最终都会对加密后的二进制数据进行Base64编码,起到一种二次加密的效果,其实呢Base64从严格意义上来说的话不是一种加密算法,而是一种编码算 ...
- C#中Length和Count的区别(个人观点)
这篇文章将会很短...短到比你的JJ还短,当然开玩笑了.网上有说过Length和count的区别,都是很含糊的,我没有发现有 文章说得比较透彻的,所以,虽然这篇文章很短,我还是希望能留在首页,听听大家 ...
- Postman接口调试神器-Chrome浏览器插件
首先大家可以去这个地址下载 Postman_v4.1.3 这个版本,我用的就是这个版本 http://chromecj.com/web-development/2014-09/60/download. ...
- PHP类和对象之重载
PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的.属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值.读取.判断属性是否设置.销毁属性. ...
- bootstrap
访问Bootstrap中文网,下载bootstrap中文文档,选择用于生产环境的bootstrap. 在官网使用ctrl+f查找想要的内容. 这里记一下Visual Studio Code软件的用法: ...
- linux下mono的安装与卸载
我很遗憾的告诉你,这里没有安装,为什么标题里加入安装俩字呢,因为如果不加的话你会搜到这篇文章吗?哈哈!别气馁,这里会给你些安装的tips! 源码安装,git安装:建议安装路径如下,至于为什么,我也讲不 ...