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 ...
随机推荐
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- LeetCode-3LongestSubstringWithoutRepeatingCharacters(C#)
# 题目 3. Longest Substring Without Repeating Characters Given a string, find the length of the longes ...
- 菜鸟学Struts2——零配置(Convention )
又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...
- premere cs4绿色版 安装 并且 视频导出 讲解
最近室友,开始在玩视频剪辑,用的是 premere cs4 绿色版.让他遇到的最大问题也是我之前遇到的最大问题,就是视频导出. 所以我在这里上传一套自己的一点点经验吧. 接下来,我就总结一下 我是怎么 ...
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
- centos7+mono4+jexus5.6.2安装过程中的遇到的问题
过程参考: http://www.linuxdot.net/ http://www.jexus.org/ http://www.mono-project.com/docs/getting-starte ...
- 使用python抓取婚恋网用户数据并用决策树生成自己择偶观
最近在看<机器学习实战>的时候萌生了一个想法,自己去网上爬一些数据按照书上的方法处理一下,不仅可以加深自己对书本的理解,顺便还可以在github拉拉人气.刚好在看决策树这一章,书里面的理论 ...
- Angular企业级开发(3)-Angular MVC实现
1.MVC介绍 Model-View-Controller 在20世纪80年代为程序语言Smalltalk发明的一种软件架构.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并 ...
- [C#] 走进 LINQ 的世界
走进 LINQ 的世界 序 在此之前曾发表过三篇关于 LINQ 的随笔: 进阶:<LINQ 标准查询操作概述>(强烈推荐) 技巧:<Linq To Objects - 如何操作字符串 ...
- Solr 排除查询
前言 solr排除查询也就是我们在数据库和程序中经常处理的不等于,solr的语法是在定语前加[-].. StringBuilder sbHtml=new StringBuilder(); shBhtm ...