问题1:什么叫Model元数据?

  Model元数据,是针对数据类型的一种描述信息。由于复杂类型(或者说类型嵌套的存在,比如CustomerModel中有一个属性为复杂类型Address)的存在,因此Model 元数据为树形结构:

  //namespace:System.Web.Mvc
public class ModelMetadata
{
//其它成员 //当前模型类型
//倘若用数据库中树形结构解释,这个属性相当于Id
public Type ModelType { get; set; } //当前模型类型所属类型
//倘若用数据库中树形结构解释,这个属性相当于ParentId
public Type CotainerType { get; set; } }

  在ASP.NET MVC中对应被定义为类型 “ModelMetadata”,其作用主要体现在以下两个方面:

  1、控制数据类型本身及其成员属性在界面上的呈现方式;

 //namespace:System.Web.Mvc
public class ModelMetadata
{
//其它成员 //模型名称
public virtual string DisplayName { get; set; }
}

  上面代码将MVC框架定义的Model元数据精简为一个属性,该属性用于呈现Model或者Model数据中元素在UI上的显示名称。这样说过于抽象,下面的的代码是我们在MVC程序开发时候常写写的界面模型类:

 //用户界面模型
public class CustomerModel
{
[DisplayName("用户姓名")]
public string Name{get;set;} public string Gender{get;set;}
}

  给CustomerModel的 Namei属性添加DisplayName 特性,Gender属性不做任何操作,倘若在强类型视图上使用@Html.DisplayFor(d=>d.Name);  @Html.DisplayFor(d=>d.Gender)显示用户信息,会发现Name会显示“用户姓名”,而Gender属性的显示仅仅是原样输出为Gender;

  事实上,DisplayName特性就是通过改变ModelMetadata的DisplayName来达到这一效果,也就是说,特性的作用在于定制ModelMetadata。

  2、Model绑定和验证提供必不可少的元数据

  绑定以后提及,至于验证,看下面代码:

  //namespace:System.Web.Mvc
public class ModelMetadata
{
//其它成员 //是否必填
public virtual bool IsRequired{ get; set; }
}
  //用户界面模型
public class CustomerModel
{
[Required]
public string Name{get;set;} public string Gender{get;set;}
}

同理,Required特性定制了Model元数据中的IsRequired属性以达到针对模型的验证。


问题2:如何针对Model元数据进行定制?

  问题1中说明了ModelMetadata类的各属性控制了数据在UI中的呈现、验证、绑定。那么如何获取或设置ModelMetadata类的各属性呢?答案是使用特性【Attribute】。

  可以用于定制Model元数据的特性有如何:

  1、UIHintAttribute

  HtmlHelper定义了一系列模板方法,比如DisplayFor/Display、EditorFor/Editor,所谓模板方法,就是Model数据与HTML标签的封装。其效果类似于强类型的PartialView。

  UIHintAttribute特性的作用就在于为Model中的属性或者字段显示指定模板,当UI出现@Html.DisplayFor(d=>d.Name)语句,ASP.NET MVC将会用UIHintAttribute指定的模板展示Model数据。

  MVC有一套寻找模板的规则,默认吗没有指定模板情况下,MVC将从@DisplayFor(d=>d.Name)  lamba表达式中得到Name的数据类型,根据该数据类型在预定义的目录下去寻找不同的模板。而同一种数据类型模板,又可以分为编辑模板(EditorFor)、显示模板(DisplayFor)。倘若指定了一个具体的模板名称,ASP.NET MVC 会自动采用该模板来生成最终的HTML。而指定的模板通常按显示模式定义在EditorTemplates目录或DisplayTemplates目录下。这些目录可以存在于Views/Shared、Views/{ControllerName}下;

  可以做个测试。

  首先定义数据模型:

  

  public class CustomerModel
{
[UIHint("Name")]
public string Name { get; set; } public string Gender { get; set; }
}

  通过UIHint特性指定了显示模板为“Name”;

  控制器中实例一个CustomerModel对象,并传递给视图View。

  public ActionResult Index()
{
CustomerModel model = new CustomerModel()
{
Name = "小李",
Gender = "男"
};
return View(model);
}

新建View如下:

 <body>
<div>
@Html.DisplayFor(d=>d.Name)<br />
@Html.DisplayFor(d => d.Gender)
</div>
</body>
</html>

主要Gender属性我们并没有指定显示模板,接着需要在DisplayTemplates目录下新建Name 视图:

@model string

  <h3 style="color:red;">我是自定义模板:@Html.TextBox(Model,Model)</h3>

 最终运行结果如下:

  

  

  APS.NET MVC预定义模板总共有这么几个:

 
模板名称 模板作用 模板说明
EmailAddress Emal地址呈现 仅具有显示模式
HiddenInput

显示模式下文本显示;

编辑模式下文本+一个隐藏的<inptu>

HiddenInput(DisplayValue=false)

时,显示模式、编辑模式显示文本均消失。

Html 将模型数据中包含的HTML原样呈现 仅限于显示模式,效果与Html.Raw()相同
Text与String                         ---- 显示模式下直接以文本的形式输出,编辑模式下对应一个单行文本框
MultilineText 多行文本(<input type="text"/>) 仅限于编辑模式
Password 密码框 仅限于编辑模式
Decimal 小数位统一化为两位小数 显示模式:文本;标记哦是:单行文本框
Boolean                        ---- 显示模式:一个checkbox,disabled=true;编辑模式:一个chekbox,加一个隐藏的checkbox,两者name相同,value相异
Colloection 集合数据呈现 ……………………
Object 备胎 找不到其它,最终就是它。根据元数据DisplayName生成一个<div>
     

  2.HiddenInputAttribute与ScaffoldColumnAttribute

  通过应用HiddenInputAttribute,该特性的目标对象以只读的形式显示出来,如果不希望显示,可以设置特性的DisplayValue为false([HiddenInput(DisplayValue=false)])。

  通过应用ScaffoldColumnAttribute,该特性的目标对象不会出现在最终生成的Html中,区别与HiddenInputAttribute,HiddenInputAttribute目标元素会以type=hidden的形式出现在最终生成的Html当中;

  3.DataTypeAttribute与DisplayFormatAttribute

  这里的DataTypeAttribute不同于CLR类型,而是通过系统定义的枚举类型:DataType来表示具有某种显示格式的数据类型。枚举DataType定义如下:

  

  // 摘要:
// 表示与数据字段和参数关联的数据类型的枚举。
public enum DataType
{
// 摘要:
// 表示自定义的数据类型。
Custom = ,
//
// 摘要:
// 表示时间上的一刻,以日期和当天的时间表示。
DateTime = ,
//
// 摘要:
// 表示日期值。
Date = ,
//
// 摘要:
// 表示时间值。
Time = ,
//
// 摘要:
// 表示对象存在的一段连续时间。
Duration = ,
//
// 摘要:
// 表示电话号码值。
PhoneNumber = ,
//
// 摘要:
// 表示货币值。
Currency = ,
//
// 摘要:
// 表示所显示的文本。
Text = ,
//
// 摘要:
// 表示一个 HTML 文件。
Html = ,
//
// 摘要:
// 表示多行文本。
MultilineText = ,
//
// 摘要:
// 表示电子邮件地址。
EmailAddress = ,
//
// 摘要:
// 表示密码值。
Password = ,
//
// 摘要:
// 表示 URL 值。
Url = ,
//
// 摘要:
// 表示图像的 URL。
ImageUrl = ,
}

事实上,DataTypeAttribute是一个验证特性,MVC在数据绑定期间将会根据应用了DataTypeAttribute的目标元素验证。 

DisplayFormatAttribure用于控制目标元素的显示形式。

  4 其它

  EditableAttribute与ReadOnlyAttributr控制目标元素的可读写性,两者实质等同,同时出现的情况下,前者具有更高的优先级;

  DisplayAttribute与DisplayNameAttribute 为目标元素定义一些说明性文字。同时出现的情况下,前者具有更高的优先级;此外,由于DisplayAttribute设置的文字都是面向最终用户的,所以有必要对其斤西瓜本地化,所以该特性提供了ResourceType属性用于代表采用的资源文件类型。

  RequiredAttribute顾名思义,其将目标元素设置为必需的数据成员。

  

最新文章

  1. 20161020001 DataGridView 选中的 DataGridViewCheckBoxCell 不添加重复项
  2. Calculating simple running totals in SQL Server
  3. Spring 框架的设计理念与设计模式分析
  4. git 10.8
  5. iOS socket原理及连接过程详解
  6. selenium 学习笔记 ---新手学习记录(10) 问题总结(java)--poi--excel 操作
  7. ipv6加英文的中括号访问
  8. the first simple html page generated by div and table tags
  9. linux CentOS6.5 yum安装mysql 5.6
  10. Docker 核心技术之仓库
  11. Python的内置方法
  12. android okHttp 无线程Post请求
  13. Java框架spring Boot学习笔记(二):Hello Spring Boot、以及项目属性配置
  14. 浏览器上安装vue devtools
  15. PAT L2-027 名人堂与代金券
  16. topcoder srm 515 div1
  17. Redis启动与使用
  18. 沉淀再出发:如何在eclipse中查看java的核心代码
  19. 小白用Android MVP-初体验(一)
  20. 对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr&lt;class&gt;、实现Ptr_vector

热门文章

  1. 下载uboot的调试版本到开发板的sdram中运行
  2. 遍历input。select option 选中的值
  3. (三)、Express 路由、静态文件、
  4. 【转】HTML5新增元素兼容旧浏览器方法
  5. mariadb DML语句及用户授权
  6. Nginx+Tomcat+Memcached集群
  7. 当数据0跟if判断冲突的时候
  8. php 安装redis扩展
  9. 转载:监控每个节点(jvm部分)
  10. Java之HttpURLConnection的变态事: Keep-Alive