MVC系统学习4—ModelMetaData
在Mvc R2中,新引入了一些扩展方法,如后面带一个for的方法,这些扩展方法会根据Model的属性自定生成相应的Html元素,如Html.EditFor(Model=>Model.IsApprove),当IsApproved为布尔类型时显示checkbox文本框,这样能简化我们的工作并且能够利用到ModelBinding。当我们调用Html.EditFor的时候,会调用到TemplateHelpers的方法去查找相应的模板,框架本来定义好了两个模板,就是DefaultDisplayTemplates和DefaultEditorTemplates分别对应着显示Display和Edit编辑。在TemplateHelpers里面定义着两个字典,键是类型名称,值是模板名称。这里就需要引出另外一个类,就是ModelMetaData。其是模型类型信息的包装,还有一些和显示相关的。ModelMetaDataProvider是负责从类型获取ModelMetaData。下图反映了ModelMetaData的真实情况。

一. ModelMetaDataProvider
ModelMetaDataProvider是一个抽象类。下面一幅图能准确放映ModelMetaData和ModelMetaDataProvider的关系。在mvc框架下默认的ModelMetaDataProvider是DataAnnotationsModelMetadataProvider。我们也可以自己定义一个Provider,然后通过在Global文件中设置ModelMetadataProviders.Current实现我们自己的Provider。使用DataAnnotationsModelMetadataProvider的好处就是它内建支持.NET中的Data Annotation特性。怎么个内建支持法?他的CreateMetadata方法会查找作用在模型下的某些特性,这些特性是指System.ComponentModel.DataAnnotations命名空间下的元数据特性,通过给我们的MVC模型类或者类的属性添加这些特性能控制显示或者在验证时期作用。

二.System.ComponentModel.DataAnnotations命名空间下的元数据特性
1.DataTypeAttribute: 属性允许使用比数据库内部类型更加具体的类型来标记字段。类型名称选自 DataType 枚举类型。例如,可以将包含电子邮件地址的字符串数据字段指定为 EmailAddress 类型。字段模板随后将访问此信息,以修改数据字段的处理方式。
2.DisplayFormatAttribute:指定如何显示数据字段以及如何设置数据字段的格式。这里需要注意一点,这个特性只能作用于属性或者字段,NullDisplayText 是表示当属性为空的时候的显示方式。
3.MetadataTypeAttribute:指定要与数据模型类关联的元数据类。当我们可以将模型的定义和对模型MetaData的定义分开。
public partial class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public Address HomeAddress { get; set; }
public bool IsApproved { get; set; }
} [MetadataType(typeof(PersonMetadata))]
public partial class Person
{
// This class is only used as a source of metadata
private class PersonMetadata
{ [HiddenInput(DisplayValue = false)] public int PersonId { get; set; } [DisplayName("First name")] public string FirstName { get; set; }
[DisplayName("Last name")] public string LastName { get; set; }
// Also add any other properties for which you want to supply metadata
}
}
接下来其他的都是比较容易的:

4.此外还有一个DisplayName属性,其是在System.ComponentModel命名空间下的。用户控制显示是的字段名称。还有Mvc的HiddenInput用户控制以hidden隐藏域的形式显示。
三.上面这些特性的作用
前面已经有提到过,这些特性的作用是用在显示和验证。我们定义好模型利用Html.Html.EditorForModel()能帮助框架能帮助我们显示相应的编辑页面。而且当我们提交的时候,还能自动利用到ModelBinder,而那些验证的特性主要是在实现ModelBinder绑定功能的时候验证客户端的提交是否和模型中特性的定义一致,如果不一致ModelState的Error就会记录,ModelState的IsValid属性就为false。利用我为模型中的Name字段添加了特性Require,但是当我提交的时候,Name属性对应的表单值为空,则就会出错。可以得知在定义这些特性后,利用ModelBinder能自动帮助我们实现数据验证。
四.Mvc自带的验证功能
Mvc验证的相关类的框架大致如下图:

这里的核心类是ModelValidator,其通过验证规则和提交的数据产生验证结果ModelValidationResult。而ModelValidatorProvider是根据ModelMetaData和ControllerContext以及Attribute生成ModelValidator的。继承自ModelValidatorProvider的三个子类分别重载实现了GetValidators方法。
DataAnnotationsModelValidatorProvider:根据ModelMetaData和作用于Model的System.ComponentModel.DataAnnotations attributes 来产生验证规则。
ClientDataTypeModelValidator:用法暂时还不是很明白
DataErrorInfoModelValidatorProvider:用法也暂时不是很明白
从上面可以得出ModelValidator是一个抽象类,具体的验证实现是由其子类实现的,下面有一副图能反映具体的类框架图。DataAnnotationModelValidator继承自Model-Validator,而泛型类DataAnnotationModelValidator<TAttribute>有继承自DataAnnotationModelValidator。接下来System.ComponentModel.DataAnnotations的各个验证特性分别会对应着一个继承自DataAnnotationModelValidator<TAttribute>的类。这里的用法会在另外一篇文章介绍!

五.自定义模板:
在前面讲过,当我们使用类似DisplayFor这样的Html辅助函数的时候,框架会根据呈现的模型的类型去查找相应的模板进行显示。我们也可以自己定义模板来显示某些类型。做法是在Shared下添加DisplayTemplates或者EditTemplates分别对应着显示和编辑模板。然后添加自定义控件,自定义控件的名称和模型或者类型名称一致。这样当进行显示的时候,自定的模板会先覆盖框架默认的模板。这里当然还要注意一点就是Mvc关于模板的选择顺序。以下列出的是从上到下的优先选择顺序。
- 在EditorFor方法中显示指定的模板名称,Html.EditorFor(x => x.SomeProperty , “My Template”)。
- 对应Model的元数据描述,比如在属性上添加特性[UIHint(“My Template”)]
- Model的元数据描述的数据类型,比如[DataType(DataType.EmailAddress)]
- 对应属性的真实.NET 类型
- 对于可以被转化成string的简单类型,使用String模板
- Model的父类属性也会被转化
- 如果属性实现了IEnumable,将选择Collection模板
- 最后使用Object模板
MVC系统学习4—ModelMetaData的更多相关文章
- MVC系统学习1—MVC执行流程
用MVC来做开发也有一段时间了,但是感觉一直没入门,就徘徊在似懂非懂的层次,和去年刚毕业学习WebForm时一样,当时通过张子阳老兄的几篇文章,明白了请求处理流程,页面生命周期才真正明白了WebFor ...
- MVC系统学习5——验证
其实关于Mvc的验证在上一篇已经有讲过一些了,可以通过在我们定义的Model上面添加相应的System.ComponentModel.DataAnnotations空间下的验证属性.在服务器端通过Mo ...
- MVC系统学习6—Filter
Mvc的过滤器是特性类,可以使我们在执行Action之前,执行Action之后,执行Action发生异常时,编写相关的处理代码实现某些逻辑.下面是四个基本的Filter接口. 上面这四个基本的Filt ...
- MVC系统学习2—MVC路由
在MVC下不是通过对物理文件的映射来实行访问的,而是通过定义后的路由Url来实现访问的.在前一篇讲到我们是在全局文件下进行路由配置. routes.MapRoute( & ...
- MVC系统学习3—ModelBinder
在ASP.NET MVC中,每个请求都被映射到一个Action方法,我们可以在action的方法中定义相应类型的参数,View中通过post.get方式提交的request参数,只要名称一致就会对应到 ...
- Mvc系统学习9——Areas学习
在Mvc2.0中,新增加了一个特性就是Areas.在没有有使用Areas的情况下,我们的Mvc项目组织是下面这样的.当项目庞大的时候,Controllers,Model,View文件下下面势必会有很多 ...
- MVC系统学习7—Action的选择过程
在Mvc源码的ControllerActionInvoker的InvokeAction方法里面有一个FindAction方法,FindAction方法在ControllerDescriptor里面定义 ...
- MVC系统学习8——AsyncController
关于为什么使用异步Controller,这里不做备忘,三岁小孩都懂.主要的备忘是如何使用AsyncController. //这个action以Async结尾,并且返回值是void public vo ...
- 零基础如何系统学习Java Web
零基础如何系统学习Java Web? 我来给你说一说 你要下决心,我要转行做开发,这样你才能学成. 你要会打字,我公司原来有一个程序员,打字都是两个手一指禅,身为程序员你一指禅怎么写出的代码,半个 ...
随机推荐
- Linux常用命令分类
目录:相对路径和绝对路径. 绝对路径:路径的写法[一定由根目录 / 写起],例如: /usr/share/doc 这个目录. 相对路径:路径的写法[不是由 / 写起],例如由 /usr/share/d ...
- bzoj 1709: [Usaco2007 Oct]Super Paintball超级弹珠【枚举】
k是1e5范围的,吗? 注意到n只有100,这意味着k去重之后之后n^2,也就是1e4! 然后就可以愉快的n^4枚举了,枚举每个格子,再枚举每个敌人,如果当前格子射不到敌人则退出,否则满足所有敌人则a ...
- 清北考前刷题day2早安
/* 做法一:按h sort一遍,对于一段区间[i,j],高度花费就是h[j]-h[i] 然后枚举区间,把区间内C排序,一个一个尽量选即可. n^3logn 标算:n^3 dp 高度排序,保证从前往后 ...
- 洛谷P4397 [JLOI2014]聪明的燕姿
传送门 dfs的时候莫名其妙深度太大过不了……然后死活找不出哪里错…… 首先,约数和这东西是个积性函数,或者直接点的话就是如果$$n=p_1^{a_1}p_2^{a_2}p_3^{a_3}…p_m^{ ...
- Window对象与DOM
目前,前端插件数不胜数,比如有移动端滑动特效插件Swiper,下拉刷新的iScroll,弹出框插件layer,还有我们经常使用的JQuery,jquery.mobile等,这些插件能够满足我们日常的基 ...
- 程序员必知的LinuxShell命令
程序员必知的LinuxShell命令 grep (Globle Regular Expression Print全局正则表达式) 命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的 ...
- 逻辑回归(Logistic Regression)推导
出自BYRans博客:http://www.cnblogs.com/BYRans/ 本文主要讲解分类问题中的逻辑回归.逻辑回归是一个二分类问题. 二分类问题 二分类问题是指预测的y值只有两个取值(0或 ...
- Fiddler—重复发送一个请求的设置
https://jingyan.baidu.com/article/b2c186c829a85dc46ff6ff60.html 选中一个request——>Reissue Sequentaill ...
- [转]最值得拥有的免费Bootstrap后台管理模板
在PHP开发项目中,后台管理因为面向群体相对比较固定,大部分以实现业务逻辑和功能.使用Bootstrap后台模板可以让后端开发很轻松的就展现给客户一个响应式的后台,节约前端开发的时间.下面PHP程序员 ...
- 08Webpage Form
Webpage Form 表单(form)在网页中主要负责数据采集功能.一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域:包含 ...