ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供
一. 元数据描述类型ModelMetadata
模型元数据是对Model的描述信息,在ASP.NET MVC框架中有非常重要的作用,在模型绑定,模型验证,模型呈现等许多地方都有它的身影。描述Model元数据的基本类型是ModelMetadata,日常开发中我们建立的ViewModel,在上面的声明的许多属性最终都会反应的该类型上,它的具体定义如下:
public class ModelMetadata
{
// 摘要:
// 默认顺序值 10000。
public const int DefaultOrder = ; // 摘要:
// 初始化 System.Web.Mvc.ModelMetadata 类的新实例。
//
// 参数:
// provider:
// 提供程序。
//
// containerType:
// 容器的类型。
//
// modelAccessor:
// 模型访问器。
//
// modelType:
// 模型的类型。
//
// propertyName:
// 模型的名称。
public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName); // 摘要:
// 获取包含有关模型的其他元数据的字典。
//
// 返回结果:
// 包含有关模型的其他元数据的字典。
public virtual Dictionary<string, object> AdditionalValues { get; }
//
// 摘要:
// 获取或设置模型的容器的类型。
//
// 返回结果:
// 模型的容器的类型。
public Type ContainerType { get; }
//
// 摘要:
// 获取或设置一个值,该值指示在窗体中回发的空字符串是否应转换为 null。
//
// 返回结果:
// 如果在窗体中回发的空字符串应转换为 null,则为 true;否则为 false。默认值为 true。
public virtual bool ConvertEmptyStringToNull { get; set; }
//
// 摘要:
// 获取或设置有关数据类型的元信息。
//
// 返回结果:
// 有关数据类型的元信息。
public virtual string DataTypeName { get; set; }
//
// 摘要:
// 获取或设置模型的说明。
//
// 返回结果:
// 模型的说明。默认值为 null。
public virtual string Description { get; set; }
//
// 摘要:
// 获取或设置模型的显示格式字符串。
//
// 返回结果:
// 模型的显示格式字符串。
public virtual string DisplayFormatString { get; set; }
//
// 摘要:
// 获取或设置模型的显示名称。
//
// 返回结果:
// 模型的显示名称。
public virtual string DisplayName { get; set; }
//
// 摘要:
// 获取或设置模型的编辑格式字符串。
//
// 返回结果:
// 模型的编辑格式字符串。
public virtual string EditFormatString { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示是否应该使用关联的 HTML 元素呈现模型对象。
//
// 返回结果:
// 如果包含模型对象的关联 HTML 元素应包含在该对象中,则为 true;否则为 false。
public virtual bool HideSurroundingHtml { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示模型是否为复杂类型。
//
// 返回结果:
// 一个值,指示 MVC 框架是否将模型视为复杂类型。
public virtual bool IsComplexType { get; }
//
// 摘要:
// 获取一个值,该值指示类型是否可为 null。
//
// 返回结果:
// 如果该类型可为 null,则为 true;否则为 false。
public bool IsNullableValueType { get; }
//
// 摘要:
// 获取或设置一个值,该值指示模型是否为只读。
//
// 返回结果:
// 如果该模型为只读,则为 true;否则为 false。
public virtual bool IsReadOnly { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示模型是否为必需的。
//
// 返回结果:
// 如果该模型是必需的,则为 true;否则为 false。
public virtual bool IsRequired { get; set; }
//
// 摘要:
// 获取模型的值。
//
// 返回结果:
// 模型的值。有关 System.Web.Mvc.ModelMetadata 的更多信息,请参见 Brad Wilson 的博客上的文章 ASP.NET
// MVC 2 Templates, Part 2: ModelMetadata
public object Model { get; set; }
//
// 摘要:
// 获取模型的类型。
//
// 返回结果:
// 模型的类型。
public Type ModelType { get; }
//
// 摘要:
// 获取或设置要为 null 值显示的字符串。
//
// 返回结果:
// 要为 null 值显示的字符串。
public virtual string NullDisplayText { get; set; }
//
// 摘要:
// 获取或设置一个值,该值表示当前元数据的顺序。
//
// 返回结果:
// 当前元数据的顺序值。
public virtual int Order { get; set; }
//
// 摘要:
// 获取模型元数据对象的集合,这些对象描述模型的属性。
//
// 返回结果:
// 用于描述模型属性的模型元数据对象的集合。
public virtual IEnumerable<ModelMetadata> Properties { get; }
//
// 摘要:
// 获取属性名称。
//
// 返回结果:
// 属性名称。
public string PropertyName { get; }
//
// 摘要:
// 获取或设置提供程序。
//
// 返回结果:
// 提供程序。
protected ModelMetadataProvider Provider { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示是否启用请求验证。
//
// 返回结果:
// 如果启用了请求验证,则为 true;否则为 false。
public virtual bool RequestValidationEnabled { get; set; }
//
// 摘要:
// 获取或设置短显示名称。
//
// 返回结果:
// 短显示名称。
public virtual string ShortDisplayName { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示属性是否应显示在只读视图(如列表和详细信息视图)中。
//
// 返回结果:
// 如果应在只读视图中显示模型,则为 true;否则为 false。
public virtual bool ShowForDisplay { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示是否应在可编辑视图中显示模型。
//
// 返回结果:
// 如果应在可编辑视图中显示模型,则为 true;否则为 false。
public virtual bool ShowForEdit { get; set; }
//
// 摘要:
// 获取或设置模型的简单显示字符串。
//
// 返回结果:
// 模型的简单显示字符串。
public virtual string SimpleDisplayText { get; set; }
//
// 摘要:
// 获取或设置一个提示,该提示建议要为此模型使用哪个模板。
//
// 返回结果:
// 一个提示,建议要为此模型使用哪个模板。
public virtual string TemplateHint { get; set; }
//
// 摘要:
// 获取或设置可用作水印的值。
//
// 返回结果:
// 水印。
public virtual string Watermark { get; set; } // 摘要:
// 从模型的 System.Linq.Expressions.Expression 参数返回元数据。
//
// 参数:
// expression:
// 一个标识模型的表达式。
//
// viewData:
// 视图数据字典。
//
// 类型参数:
// TParameter:
// 参数的类型。
//
// TValue:
// 值的类型。
//
// 返回结果:
// 元数据。
public static ModelMetadata FromLambdaExpression<TParameter, TValue>(Expression<Func<TParameter, TValue>> expression, ViewDataDictionary<TParameter> viewData);
//
// 摘要:
// 从模型的表达式参数中获取元数据。
//
// 参数:
// expression:
// 一个标识模型的表达式。
//
// viewData:
// 视图数据字典。
//
// 返回结果:
// 模型的元数据。
public static ModelMetadata FromStringExpression(string expression, ViewDataDictionary viewData);
//
// 摘要:
// 获取模型的显示名称。
//
// 返回结果:
// 模型的显示名称。
public string GetDisplayName();
//
// 摘要:
// 返回模型的简单说明。
//
// 返回结果:
// 模型的简单说明。
protected virtual string GetSimpleDisplayText();
//
// 摘要:
// 获取模型的验证程序的列表。
//
// 参数:
// context:
// 控制器上下文。
//
// 返回结果:
// 模型的验证程序的列表。
public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context);
}
这个类定义了有很多的属性,下面分别分组介绍:
a. 基本属性
public Type ContainerType { get; }
public virtual bool IsComplexType { get; }
public bool IsNullableValueType { get; }
public object Model { get; set; }
public Type ModelType { get; }
public string PropertyName { get; }
ContainerType表示容器的类型, 对对象类型本身,无类型定义包括它,其ContainerType是null, 其属性的ModelMetadata的ContainerType是对象类型
IsComplexType表示是否复杂类型, 判断的依据是是否与字符串进行转换, return !(TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string));
IsNullableValueType 表示是否可空值类型
Model 表示当前的模型对象
ModelType 表示Model的类型
PropertyName 表示属性的名称,对应属性元数据时
protected ModelMetadataProvider Provider { get; set; }
表示元数据提供者
public virtual Dictionary<string, object> AdditionalValues
{
get { return _additionalValues; }
}
表示定义的附加的元数据,通过System.Web.Mvc.AdditionalMetadataAttribute实现,该属性实现IMetadataAware接口,在ModelMetadata对象创建后添加元数据到AdditionValues集合。
b. 定制元数据信息
1)UIHintAttribute 声明模板名称,对应ModelMetadata的TemplateHint属性
2)HiddenInputAttribute声明显示为将属性值呈现为hidden元素,同时属性值显示为只读,通过其DisplayValue可隐藏显示,
对应ModelMetadata两个属性:TemplateHint和HideSurroundingHtml, 注意UIHintAttribute设置具有更高的优先级
3)ScaffoldColumnAttribute声明元素是否呈现在html中,对应ModelMetadata的ShowForDisplay和ShowForEdit属性
4)DateTypeAttribute 对应ModelMetadata的DataTypeAttribute
5)DisplayFormat 对应ModelMetadata的ConvertTEmptyStringToNull, NullDisplayText,DisplayFormatString, EditFormatString
6)EditableAttribute和ReadonlyAttribute 对应ModelMetadata的IsReadOnly
7)DisplayAttribute和DisplayNameAttribute 对应ModelMetadata的DisplayName, ShortDisplayName, Description, Order, Watermark
8)RequiredAttribute 对应ModelMetadata的IsRequired
9)AllowHtmlAttribute 对应ModelMetadata的RequestValidationEnabled
二.元数据提供机制ModelMetadataProvider
ModelMetadata提供机制是通过ModelMetadataProvider来实现, ModelMetadataProvider是一个抽象类,定义如下:
public abstract class 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);
}
在ASP.NET MVC元数据提供入口是ModelMetadataProviders类,实现代码如下:
public class ModelMetadataProviders
{
private static ModelMetadataProviders _instance = new ModelMetadataProviders();
private ModelMetadataProvider _currentProvider;
private IResolver<ModelMetadataProvider> _resolver; internal ModelMetadataProviders(IResolver<ModelMetadataProvider> resolver = null)
{
_resolver = resolver ?? new SingleServiceResolver<ModelMetadataProvider>(
() => _currentProvider,
new CachedDataAnnotationsModelMetadataProvider(),
"ModelMetadataProviders.Current");
} public static ModelMetadataProvider Current
{
get { return _instance.CurrentInternal; }
set { _instance.CurrentInternal = value; }
} internal ModelMetadataProvider CurrentInternal
{
get { return _resolver.Current; }
set { _currentProvider = value ?? new EmptyModelMetadataProvider(); }
}
}
从中我们看到框架默认的元数据提供类型是CachedDataAnnotationsModelMetadataProvider, 整个交互的类图如下:


ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供的更多相关文章
- ASP.NET MVC5学习笔记之Action参数模型绑定基本过程
当我们在Controller中定义一个Action,通常会定义一个或多个参数,每个参数称为一个模型,ASP.NET MVC框架提供了一种机制称为模型绑定,会尝试自动从请求的信息中实例化每一个模型并赋值 ...
- ASP.NET MVC5学习笔记之Action参数模型绑定值提供体系
这一节我们关注模型绑定的值提供体系,先来介绍几个重要的接口 一. IValueProvider,接口定义如下: public interface IValueProvider { bool Conta ...
- ASP.NET MVC5学习笔记01
由于之前在项目中也使用MVC进行开发,但是具体是那个版本就不是很清楚了,但是我觉得大体的思想是相同的,只是版本高的在版本低的基础上增加了一些更加方便操作的东西.下面是我学习ASP.NET MVC5高级 ...
- ASP.NET MVC5学习笔记之Filter提供体系
前面我们介绍了Filter的基本使用,但各种Filter要在合适的时机运行起来,需要预先准备好,现在看看ASP.NET MVC框架是怎么做的. 一.Filter集合 在ControlerActionI ...
- ASP.NET MVC5学习笔记之Controller同步执行架构分析
在开始之前,声明一下,由于ASP.NET MVC5正式发布了,后面的分析将基于ASP.NET MVC5最新的源代码.在前面的内容我们分析了怎样根据路由信息来确定Controller的类型,并最终生成C ...
- ASP.NET MVC5 学习笔记-1 控制器、路由、返回类型、选择器、过滤器
[TOC] 1. Action 1.1 新建项目 新建项目->Web->Asp.net Web应用程序,选择MVC,选择添加测试. 在解决方案上右键,选择"管理NuGet程序包& ...
- ASP.NET MVC5学习笔记之Filter基本介绍
Filter是ASP.NET MVC框架提供的基于AOP(面向方面)设计,提供在Action执行前后做一些非业务逻辑通用处理,如用户验证,缓存等.现在来看看Filter相关的一些类型信息. 一.基本类 ...
- ASP.NET MVC5 学习笔记-2 Razor
1. Razor @*注释*@ 你在用 @Request.Browser.Browser, 发送邮件给support@qq.com, 转义@@qq @{ var amounts = new List& ...
- ASP.NET MVC5 学习笔记-3 Model
1. Model 1.1 添加一个模型 注意,添加属性时可以输入"prop",会自动输入代码段. public class CheckoutAccount { public int ...
随机推荐
- Qt编译安装后中文无法显示问题
闲的蛋疼,把Ubuntu删了,再装10.04的时候,QT编译后运行自己的程序已经不能显示中文了,只能显示英文,字体贼丑... 想了各种办法,都没解决.. 最后:终于搞定: apt-get instal ...
- Android wifi状态三种广播
public class NetworkConnectChangedReceiver extends BroadcastReceiver{ @Override public voi ...
- POJ2376_Cleaning Shifts_C++
题目:http://poj.org/problem?id=2376 英文题强行看不懂,只看的懂输入输出,输入n,m,下接n行每行一个区间两个数左端点 l,有端点 r 给出n个闭区间,求选择最少的区间能 ...
- jmeter随笔(5)--断言中正则表达式的特殊字符问题和中文乱码显示问号的问题
最近在工作中,对jmeter实践的点滴的记录,这里分享交流,不一定正确,仅供参考和讨论,有想法的欢迎留言.谈论,手机上图片如果不清晰,请点击[阅读原文]查看. 问题:今天QQ群一朋友遇到jmeter的 ...
- 静态链表 C语言描述
静态链表1.下标为0的游标存放最后存放数据节点的游标,即是第一个没有存放元素(备用链表)的下标2.最后一个的节点存放第一个由数值得下标3.第一个和最后一个都不存放数据 即是备用链表的第一个的下标 4. ...
- php array(object) 与xml相互转换
private function _array_to_xml($source, $charset='utf-8'){ $array = json_decode($source); $pre = '&l ...
- Android基础总结(10)——手机多媒体的运用:通知、短信、相机、视频播放
Android提供了一系列的API,是我们可以在程序中调用很多手机的多媒体资源,从而编写出更加丰富的应用程序. 1.通知的使用 通知(Notification)是Android中比较有特色的一个功能, ...
- android 存储概念
首先,我们得知道android中有内部存储(与内存要区分开来)和外部存储. 内部存储容量较小,尽量少使用,sqlite及SharePreference的数据均在内部存储当中. Log.i(" ...
- 【Hibernate 7】浅谈Hibernate的缓存机制
一.Hibernate缓存机制简介 对于Hibernate本身来说,它的缓存主要包括三部分:session缓存(一级缓存).二级缓存.查询缓存. 1.1,session缓存 随着session的关闭而 ...
- 【Hibernate 3】一对一映射配置
一.一对一映射简介 一对一关联映射有两种实现策略: 第一种:主键关联,即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联 ...