ASP.NET MVC Model元数据(二)
ASP.NET MVC Model元数据(二)
前言
在上篇中,给大家留个对Model元数据的印象,并没有对Model元数据有过多的讲解,而在本篇中也不会对Model元数据的本身来解释,而是针对于它的生成过程,让大家能够清楚的了解到系统框架是在什么时候生成Model元数据的,对于Model元数据生成篇幅初定为两篇,本篇为它的整体的生成过程,下篇则为详细的生成过程并且会对它本身做一个粗略的介绍,希望大家看完能够有所收获
Model元数据
- 什么是Model元数据?
- 生成Model元数据的过程【一】
- 生成Model元数据的过程【二】
- ModelMetaData的定义、详解
- Model元数据应用(常用特性应用)-1
- Model元数据应用(自定义视图模板)-2
- Model元数据应用(IMetadataAware接口使用)-3
生成Model元数据的过程【一】
还是如前篇说的那样,既然叫Model元数据(Model指的是视图模型)那么肯定跟Model有关系了,而在我们MVC项目中一般是什么时候会对Model进行操作呢?一般情况下都是在通过控制器的行为请求一个视图的时候,而控制器行为的参数即为Model,然后在行为方法中做一些处理然后再传递给视图。然后再根据上篇最后的一个示意图来看,
图1

生成Model元数据的地方已经锁定到了行为方法,想象一下肯定是不可能在行为方法中来生成的,因为那是我们自定义逻辑的地方。那是在什么地方呢?
想必大家看过之前的对过滤器篇幅的介绍,在ASP.NET MVC 过滤器(三)中对行为过滤器的执行过程讲解的时候,中间有提到过模型绑定器,并且说到了系统框架所要使用到的自定义模型绑定器,而使用这个自定义模型绑定器所需要的两个参数是非常重要的,一个是表示当前控制器上下文的对象ControllerContext,另一个则是生成Model元数据的关键,也是调用自定义模型绑定器的关键参数ModelBindingContext类型。看下
图2

而在ModelBindingContext类型中有个重要的属性,即为Model元数据类型ModelMetadata,由此可以知道在我们的控制器行为执行之前,对应控制器行为的Model的Model元数据ModelMetadata类型已经生成了。(这部分内容详见过滤器篇幅)
而它是怎么生成的呢?是通过系统框架中默认提供的提供程序来生成的,是哪些个类型呢?
图3

那我们就先看一下最顶层的基类ModelMetadataProvider的定义:
代码1-1
public abstract class ModelMetadataProvider
{
// 摘要:
// 在派生类中重写时,初始化派生自 System.Web.Mvc.ModelMetadataProvider 类的对象的新实例。
protected ModelMetadataProvider();
public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
}
非常明白的定义,三个抽象方法,这里我们只需先看GetMetadataForType()方法,其它两个暂时不管下篇中会有讲到,因为先看GetMetadataForType()方法呢?因为它是生成ModelMetadata类型的入口,第一个参数暂时忽略,第二个参数嘛很重要了,是ParameterDescriptor类型的ParameterType属性,表示着Model的类型(也就是控制器方法参数的Type类型),现在我们来看下图4
图4

图4中蓝色线条为主要流程,红色线条是在蓝色处理之后执行的流程。
上面说到,入口方法是为抽象方法,那是怎么具体实现的呢,从图4中可以看到是由实现了ModelMetadataProvider的类型AssociatedMetadataProvider类型来进行处理的,从图4可以看到首先是获取一个AttributeList的类型,AttributeList类型表示着从AssociatedMetadataProvider类型GetMetadataForType()方法参数modelType类型上的特性集合,对了AssociatedMetadataProvider类型是比较重要的类型,我们先来看一下它的定义:
public abstract class AssociatedMetadataProvider : ModelMetadataProvider
{
protected AssociatedMetadataProvider();
protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes);
public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor);
public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type);
}
方法有点多,暂时不用管,大多数方法都是用来在递归生成Model元数据的时候使用的(具体的过程会在下篇中讲解)。好了切回主题接着上面的内容来说,AttributeList类型的由来,是通过ModelMetadataProvider的GetTypeDescriptor()方法根据Model的类型(这里暂且先这么理解,等看完下个篇幅就会知道这里也有可能是Model中的属性类型)来生成一个ICustomTypeDescriptor类型(可以想象成这是对于一种对象类型元数据描述对象的抽象定义。读起来有点绕口,但是确实是这么个意思)。而系统会有个默认的自定义实现来实现这个接口类型,我们通过这个默认的实现来获得Model类型的AttributeList类型。
在有了AttributeList类型后,我们就可以调用AssociatedMetadataProvider类型的CreateMetadata()方法来创建Model元数据对象,但是这个CreateMetadata()的定义是抽象的,而真正的实现是由继承了AssociatedMetadataProvider类型的DataAnnotationsModelMetadataProvider类型,由此过后我们生成得到ModelMetadata元数据对象(真正的过程比较繁琐,不然也不会另起一篇专门用来讲解生成的过程),得到了Model元数据对象过后并没有结束,而是继续调用了AssociatedMetadataProvider类型的ApplyMetadataAwareAttributes()方法,并在此方法中,系统框架会调用我们自定义实现了IMetadataAware接口类型的对象,来对Model元数据对象进行个性化修改,并且最后才会真正的返回Model元数据对象。
有可能看到这里有的朋友对Model元数据还是不怎么清楚和了解,朋友们急我也急,如果我分享的这些知识大家看完都不知所云那我又是何必呢。先不要急看了多少就是多少在看完这个Model元数据系列的文章后应该会有所了解,将在后续的篇章中慢慢的揭开它的秘密。谢谢大家的支持。
作者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
ASP.NET MVC Model元数据(二)的更多相关文章
- ASP.NET MVC Model绑定(二)
ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...
- 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元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...
- ASP.NET MVC Model元数据(一)
ASP.NET MVC Model元数据(一) 前言 在我初学的时候对Model元数据的概念很模糊,或者说是在大脑中没有它的一个模型,作为小白的我去看网上的一些文章还是两眼一黑啥都看不明白,然后我想退 ...
- ASP.NET MVC Model元数据
ASP.NET MVC Model元数据(三) 前言 在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- 【笔记】ASP.NET MVC Model元数据
问题1:什么叫Model元数据? Model元数据,是针对数据类型的一种描述信息.由于复杂类型(或者说类型嵌套的存在,比如CustomerModel中有一个属性为复杂类型Address)的存在,因此M ...
- ASP.NET MVC Model之二模型绑定
Asp.net mvc中的模型绑定,或许大家经常用,但是具体说他是怎么一回事,可能还是会有些陌生,那么,本文就带你理解模型绑定.为了理解模型绑定,本文会先给出其定义,然后对通过比,来得出使用模型绑定的 ...
随机推荐
- 初识Hadoop、Hive
2016.10.13 20:28 很久没有写随笔了,自打小宝出生后就没有写过新的文章.数次来到博客园,想开始新的学习历程,总是被各种琐事中断.一方面确实是最近的项目工作比较忙,各个集群频繁地上线加多版 ...
- Jquery的点击事件,三句代码完成全选事件
先来看一下Js和Jquery的点击事件 举两个简单的例子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...
- 制作类似ThinkPHP框架中的PATHINFO模式功能
一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...
- Linq表达式、Lambda表达式你更喜欢哪个?
什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...
- Hyper-V无法文件拖拽解决方案~~~这次用一个取巧的方法架设一个FTP来访问某个磁盘,并方便的读写文件
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...
- ExtJS 4.2 业务开发(二)数据展示和查询
本篇开始模拟一个船舶管理系统,提供查询.添加.修改船舶的功能,这里介绍其中的数据展示和查询功能. 目录 1. 数据展示 2. 数据查询 3. 在线演示 1. 数据展示 在这里我们将模拟一个船舶管理系统 ...
- HTML5轻松实现搜索框提示文字点击消失---及placeholder颜色的设置
在做搜索框的时候无意间发现html5的input里有个placeholder属性能轻松实现提示文字点击消失功能,之前还傻傻的在用js来实现类似功能... 示例 <form action=&quo ...
- UML图中经常用到几种的关系图例
学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...
- javascript高性能编程-算法和流程控制
代码整体结构是执行速度的决定因素之一. 代码量少不一定运行速度快, 代码量多也不一定运行速度慢. 性能损失与代码组织方式和具体问题解决办法直接相关. 倒序循环可以提高性能,如: ...
- JavaScript作用域
JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...