一. 元数据描述类型ModelMetadata

模型元数据是对Model的描述信息,在ASP.NET MVC框架中有非常重要的作用,在模型绑定,模型验证,模型呈现等许多地方都有它的身影。描述Model元数据的基本类型是ModelMetadata,日常开发中我们建立的ViewModel,在上面的声明的许多属性最终都会反应的该类型上,它的具体定义如下:

  1. public class ModelMetadata
  2. {
  3. // 摘要:
  4. // 默认顺序值 10000。
  5. public const int DefaultOrder = ;
  6.  
  7. // 摘要:
  8. // 初始化 System.Web.Mvc.ModelMetadata 类的新实例。
  9. //
  10. // 参数:
  11. // provider:
  12. // 提供程序。
  13. //
  14. // containerType:
  15. // 容器的类型。
  16. //
  17. // modelAccessor:
  18. // 模型访问器。
  19. //
  20. // modelType:
  21. // 模型的类型。
  22. //
  23. // propertyName:
  24. // 模型的名称。
  25. public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
  26.  
  27. // 摘要:
  28. // 获取包含有关模型的其他元数据的字典。
  29. //
  30. // 返回结果:
  31. // 包含有关模型的其他元数据的字典。
  32. public virtual Dictionary<string, object> AdditionalValues { get; }
  33. //
  34. // 摘要:
  35. // 获取或设置模型的容器的类型。
  36. //
  37. // 返回结果:
  38. // 模型的容器的类型。
  39. public Type ContainerType { get; }
  40. //
  41. // 摘要:
  42. // 获取或设置一个值,该值指示在窗体中回发的空字符串是否应转换为 null。
  43. //
  44. // 返回结果:
  45. // 如果在窗体中回发的空字符串应转换为 null,则为 true;否则为 false。默认值为 true。
  46. public virtual bool ConvertEmptyStringToNull { get; set; }
  47. //
  48. // 摘要:
  49. // 获取或设置有关数据类型的元信息。
  50. //
  51. // 返回结果:
  52. // 有关数据类型的元信息。
  53. public virtual string DataTypeName { get; set; }
  54. //
  55. // 摘要:
  56. // 获取或设置模型的说明。
  57. //
  58. // 返回结果:
  59. // 模型的说明。默认值为 null。
  60. public virtual string Description { get; set; }
  61. //
  62. // 摘要:
  63. // 获取或设置模型的显示格式字符串。
  64. //
  65. // 返回结果:
  66. // 模型的显示格式字符串。
  67. public virtual string DisplayFormatString { get; set; }
  68. //
  69. // 摘要:
  70. // 获取或设置模型的显示名称。
  71. //
  72. // 返回结果:
  73. // 模型的显示名称。
  74. public virtual string DisplayName { get; set; }
  75. //
  76. // 摘要:
  77. // 获取或设置模型的编辑格式字符串。
  78. //
  79. // 返回结果:
  80. // 模型的编辑格式字符串。
  81. public virtual string EditFormatString { get; set; }
  82. //
  83. // 摘要:
  84. // 获取或设置一个值,该值指示是否应该使用关联的 HTML 元素呈现模型对象。
  85. //
  86. // 返回结果:
  87. // 如果包含模型对象的关联 HTML 元素应包含在该对象中,则为 true;否则为 false。
  88. public virtual bool HideSurroundingHtml { get; set; }
  89. //
  90. // 摘要:
  91. // 获取或设置一个值,该值指示模型是否为复杂类型。
  92. //
  93. // 返回结果:
  94. // 一个值,指示 MVC 框架是否将模型视为复杂类型。
  95. public virtual bool IsComplexType { get; }
  96. //
  97. // 摘要:
  98. // 获取一个值,该值指示类型是否可为 null。
  99. //
  100. // 返回结果:
  101. // 如果该类型可为 null,则为 true;否则为 false。
  102. public bool IsNullableValueType { get; }
  103. //
  104. // 摘要:
  105. // 获取或设置一个值,该值指示模型是否为只读。
  106. //
  107. // 返回结果:
  108. // 如果该模型为只读,则为 true;否则为 false。
  109. public virtual bool IsReadOnly { get; set; }
  110. //
  111. // 摘要:
  112. // 获取或设置一个值,该值指示模型是否为必需的。
  113. //
  114. // 返回结果:
  115. // 如果该模型是必需的,则为 true;否则为 false。
  116. public virtual bool IsRequired { get; set; }
  117. //
  118. // 摘要:
  119. // 获取模型的值。
  120. //
  121. // 返回结果:
  122. // 模型的值。有关 System.Web.Mvc.ModelMetadata 的更多信息,请参见 Brad Wilson 的博客上的文章 ASP.NET
  123. // MVC 2 Templates, Part 2: ModelMetadata
  124. public object Model { get; set; }
  125. //
  126. // 摘要:
  127. // 获取模型的类型。
  128. //
  129. // 返回结果:
  130. // 模型的类型。
  131. public Type ModelType { get; }
  132. //
  133. // 摘要:
  134. // 获取或设置要为 null 值显示的字符串。
  135. //
  136. // 返回结果:
  137. // 要为 null 值显示的字符串。
  138. public virtual string NullDisplayText { get; set; }
  139. //
  140. // 摘要:
  141. // 获取或设置一个值,该值表示当前元数据的顺序。
  142. //
  143. // 返回结果:
  144. // 当前元数据的顺序值。
  145. public virtual int Order { get; set; }
  146. //
  147. // 摘要:
  148. // 获取模型元数据对象的集合,这些对象描述模型的属性。
  149. //
  150. // 返回结果:
  151. // 用于描述模型属性的模型元数据对象的集合。
  152. public virtual IEnumerable<ModelMetadata> Properties { get; }
  153. //
  154. // 摘要:
  155. // 获取属性名称。
  156. //
  157. // 返回结果:
  158. // 属性名称。
  159. public string PropertyName { get; }
  160. //
  161. // 摘要:
  162. // 获取或设置提供程序。
  163. //
  164. // 返回结果:
  165. // 提供程序。
  166. protected ModelMetadataProvider Provider { get; set; }
  167. //
  168. // 摘要:
  169. // 获取或设置一个值,该值指示是否启用请求验证。
  170. //
  171. // 返回结果:
  172. // 如果启用了请求验证,则为 true;否则为 false。
  173. public virtual bool RequestValidationEnabled { get; set; }
  174. //
  175. // 摘要:
  176. // 获取或设置短显示名称。
  177. //
  178. // 返回结果:
  179. // 短显示名称。
  180. public virtual string ShortDisplayName { get; set; }
  181. //
  182. // 摘要:
  183. // 获取或设置一个值,该值指示属性是否应显示在只读视图(如列表和详细信息视图)中。
  184. //
  185. // 返回结果:
  186. // 如果应在只读视图中显示模型,则为 true;否则为 false。
  187. public virtual bool ShowForDisplay { get; set; }
  188. //
  189. // 摘要:
  190. // 获取或设置一个值,该值指示是否应在可编辑视图中显示模型。
  191. //
  192. // 返回结果:
  193. // 如果应在可编辑视图中显示模型,则为 true;否则为 false。
  194. public virtual bool ShowForEdit { get; set; }
  195. //
  196. // 摘要:
  197. // 获取或设置模型的简单显示字符串。
  198. //
  199. // 返回结果:
  200. // 模型的简单显示字符串。
  201. public virtual string SimpleDisplayText { get; set; }
  202. //
  203. // 摘要:
  204. // 获取或设置一个提示,该提示建议要为此模型使用哪个模板。
  205. //
  206. // 返回结果:
  207. // 一个提示,建议要为此模型使用哪个模板。
  208. public virtual string TemplateHint { get; set; }
  209. //
  210. // 摘要:
  211. // 获取或设置可用作水印的值。
  212. //
  213. // 返回结果:
  214. // 水印。
  215. public virtual string Watermark { get; set; }
  216.  
  217. // 摘要:
  218. // 从模型的 System.Linq.Expressions.Expression 参数返回元数据。
  219. //
  220. // 参数:
  221. // expression:
  222. // 一个标识模型的表达式。
  223. //
  224. // viewData:
  225. // 视图数据字典。
  226. //
  227. // 类型参数:
  228. // TParameter:
  229. // 参数的类型。
  230. //
  231. // TValue:
  232. // 值的类型。
  233. //
  234. // 返回结果:
  235. // 元数据。
  236. public static ModelMetadata FromLambdaExpression<TParameter, TValue>(Expression<Func<TParameter, TValue>> expression, ViewDataDictionary<TParameter> viewData);
  237. //
  238. // 摘要:
  239. // 从模型的表达式参数中获取元数据。
  240. //
  241. // 参数:
  242. // expression:
  243. // 一个标识模型的表达式。
  244. //
  245. // viewData:
  246. // 视图数据字典。
  247. //
  248. // 返回结果:
  249. // 模型的元数据。
  250. public static ModelMetadata FromStringExpression(string expression, ViewDataDictionary viewData);
  251. //
  252. // 摘要:
  253. // 获取模型的显示名称。
  254. //
  255. // 返回结果:
  256. // 模型的显示名称。
  257. public string GetDisplayName();
  258. //
  259. // 摘要:
  260. // 返回模型的简单说明。
  261. //
  262. // 返回结果:
  263. // 模型的简单说明。
  264. protected virtual string GetSimpleDisplayText();
  265. //
  266. // 摘要:
  267. // 获取模型的验证程序的列表。
  268. //
  269. // 参数:
  270. // context:
  271. // 控制器上下文。
  272. //
  273. // 返回结果:
  274. // 模型的验证程序的列表。
  275. public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context);
  276. }

这个类定义了有很多的属性,下面分别分组介绍:

a. 基本属性

  1. public Type ContainerType { get; }
  2. public virtual bool IsComplexType { get; }
  3. public bool IsNullableValueType { get; }
  4. public object Model { get; set; }
  5. public Type ModelType { get; }
  6. 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; }

  表示元数据提供者

  1. public virtual Dictionary<string, object> AdditionalValues
  2. {
  3. get { return _additionalValues; }
  4. }

表示定义的附加的元数据,通过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是一个抽象类,定义如下:

  1. public abstract class ModelMetadataProvider
  2. {
  3. public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
  4.  
  5. public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
  6.  
  7. public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
  8. }

  在ASP.NET MVC元数据提供入口是ModelMetadataProviders类,实现代码如下:

  1. public class ModelMetadataProviders
  2. {
  3. private static ModelMetadataProviders _instance = new ModelMetadataProviders();
  4. private ModelMetadataProvider _currentProvider;
  5. private IResolver<ModelMetadataProvider> _resolver;
  6.  
  7. internal ModelMetadataProviders(IResolver<ModelMetadataProvider> resolver = null)
  8. {
  9. _resolver = resolver ?? new SingleServiceResolver<ModelMetadataProvider>(
  10. () => _currentProvider,
  11. new CachedDataAnnotationsModelMetadataProvider(),
  12. "ModelMetadataProviders.Current");
  13. }
  14.  
  15. public static ModelMetadataProvider Current
  16. {
  17. get { return _instance.CurrentInternal; }
  18. set { _instance.CurrentInternal = value; }
  19. }
  20.  
  21. internal ModelMetadataProvider CurrentInternal
  22. {
  23. get { return _resolver.Current; }
  24. set { _currentProvider = value ?? new EmptyModelMetadataProvider(); }
  25. }
  26. }

  从中我们看到框架默认的元数据提供类型是CachedDataAnnotationsModelMetadataProvider, 整个交互的类图如下:

  

ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供的更多相关文章

  1. ASP.NET MVC5学习笔记之Action参数模型绑定基本过程

    当我们在Controller中定义一个Action,通常会定义一个或多个参数,每个参数称为一个模型,ASP.NET MVC框架提供了一种机制称为模型绑定,会尝试自动从请求的信息中实例化每一个模型并赋值 ...

  2. ASP.NET MVC5学习笔记之Action参数模型绑定值提供体系

    这一节我们关注模型绑定的值提供体系,先来介绍几个重要的接口 一. IValueProvider,接口定义如下: public interface IValueProvider { bool Conta ...

  3. ASP.NET MVC5学习笔记01

    由于之前在项目中也使用MVC进行开发,但是具体是那个版本就不是很清楚了,但是我觉得大体的思想是相同的,只是版本高的在版本低的基础上增加了一些更加方便操作的东西.下面是我学习ASP.NET MVC5高级 ...

  4. ASP.NET MVC5学习笔记之Filter提供体系

    前面我们介绍了Filter的基本使用,但各种Filter要在合适的时机运行起来,需要预先准备好,现在看看ASP.NET MVC框架是怎么做的. 一.Filter集合 在ControlerActionI ...

  5. ASP.NET MVC5学习笔记之Controller同步执行架构分析

    在开始之前,声明一下,由于ASP.NET MVC5正式发布了,后面的分析将基于ASP.NET MVC5最新的源代码.在前面的内容我们分析了怎样根据路由信息来确定Controller的类型,并最终生成C ...

  6. ASP.NET MVC5 学习笔记-1 控制器、路由、返回类型、选择器、过滤器

    [TOC] 1. Action 1.1 新建项目 新建项目->Web->Asp.net Web应用程序,选择MVC,选择添加测试. 在解决方案上右键,选择"管理NuGet程序包& ...

  7. ASP.NET MVC5学习笔记之Filter基本介绍

    Filter是ASP.NET MVC框架提供的基于AOP(面向方面)设计,提供在Action执行前后做一些非业务逻辑通用处理,如用户验证,缓存等.现在来看看Filter相关的一些类型信息. 一.基本类 ...

  8. ASP.NET MVC5 学习笔记-2 Razor

    1. Razor @*注释*@ 你在用 @Request.Browser.Browser, 发送邮件给support@qq.com, 转义@@qq @{ var amounts = new List& ...

  9. ASP.NET MVC5 学习笔记-3 Model

    1. Model 1.1 添加一个模型 注意,添加属性时可以输入"prop",会自动输入代码段. public class CheckoutAccount { public int ...

随机推荐

  1. POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  2. Regional Changchun Online--Travel(最小生成树&& 并查集)

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  3. The 2013 ACM-ICPC Asia Changsha Regional Contest - A

    Alice's Print Service Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is providing print ser ...

  4. Win2D 官方文章系列翻译 - 避免内存泄漏

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-avoiding-memory-leaks/ 在托管 XAML 应用中使用 Win2D 控件时,必须谨慎处理对 ...

  5. dumpsys命令的使用及telephony.registry解读

    adb shell dumpsys,默认打印出当前系统所有的service信息,通常情况下我们并不想看那么多信息,可以在后面加上具体的服务名,比如想获取关于设备电池的信息,就可以使用以下命令: > ...

  6. FlashBuilder的快捷键

    Ctrl-F11: 执行(Run) F11: 除错(Debug) Ctrl-Alt-Down: 重复目前所在编辑列(Repeat current line ) Alt-Up: 移动本列,或选择列往上移 ...

  7. cygwin中运行命令提示command not found的解决方法

    在cygwin下运行ls等linux常见命令时出现“command not found”的提示,原因是环境变量没有配置好,因此只要将环境变量配置正确,即可正常使用.举例说明,cygwin安装在C盘根目 ...

  8. phonegap/cordova 升级版本

    调用语句 : windows用户 npm update -g cordova 如果是 mac系统的用户  使用: 查看cordova信息 npm info cordova 查看cordova 版本 查 ...

  9. shell脚本循环执行mysql语句

    参考资料:Shell脚本中执行mysql语句 需求:数据库里有张数据表存储的是用户对电影的评价(user_id movie_id rating time),但是我现在要每部电影的总评分. 解决方法: ...

  10. Android控件大全(一)——DialogFragment创建对话框

    DialogFragment在android 3.0时被引入.是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框.典型的用于:展示警告框,输入框,确认框等等. 在Dia ...