MVC3.0学习笔记之元模型元数据ModelMetaData以及模型元数据提供系统
模型元数据ModelMetaData是MVC中很重要的概念,它包括但不仅限于 模型的类型,模型包含了哪些属性,属性都是什么类型的,属性上都有什么特性。
ASP.NET MVC3.0 提供了默认的模型元数据 DataAnnotationsModelMetadata 继承自ModelMetadata(另外系统提供了默认的模型元数据提供器DataAnnotationsModelMetadataProvider)
public class DataAnnotationsModelMetadata : ModelMetadata
它的构造函数如下
public DataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Func modelAccessor, Type modelType, string propertyName, DisplayColumnAttribute displayColumnAttribute);
DataAnnotationsModelMetadata类有常用的几个属性
DisplayName 显示名称,DisplayFormatString格式字符串
TemplateHint 获取一个值选择使用哪个模版
对于DisplayName ,LabelFor<TModel, TValue> 方法中使用此属性来生成标签文本. 意思就是一旦我们的model上有定义了DispalyName特性,那么view中使用html.editForModel()方法就会自动为model的这个属性显示出label标签" <label for="username">名称</label></
[Display( Name="名称",Order=2)] //order属性改变在html页面中的排列顺序
public string username { get; set; }
html源代码:
<div class="editor-label"><label for="username">名称</label></div>
<div class="editor-field"><input class="text-box single-line" data-val="true" data-val-maxwords="名称 has too many words" data-val-maxwords-wordcount="2" data-val-required="名称 字段是必需的。" id="username" name="username" type="text" value=""> <span class="field-validation-valid" data-valmsg-for="username" data-valmsg-replace="true"></span></div>
属性username上用的Display特性就是System.ComponentModel.DataAnnotations.DisplayAttribute类提供一个通用特性,使您可以为实体分部类的类型和成员指定可本地化的字符串
另外还有一些特性来自System.Web.MVC 和 System.ComponentModel.DataAnnotations,名称凡类似 XXXXAttribute的都为特性类,都有特定的使用范围,有的限制模型属性,有的限制Contrller,有的限制Action等等。
下面列举了这2个命名空间下,内置的而且常用的特性类
1)System.Web.MVC空间下的
AcceptVerbsAttribute,ActionFilterAttribute,ActionNameAttribute,AsyncTimeoutAttribute,AuthorizeAttribute,BindAttribute,
ActionFilterAttribute 表示所有操作-筛选器特性的基类
HttpDeleteAttribute 类,表示一个特性,该特性用于限制操作方法,以便该方法仅处理 HTTP DELETE 请求
HttpGetAttribute,HttpPostAttribute 表示特性,用于限制操作方法,仅限处理PUT请求
HttpPutAttribute 表示一个特性,该特性用于限制操作方法,以便该方法仅处理 HTTP PUT 请求。
例:ActionNameAttribute 指定action的实际actionname,用法如下
[ActionName()]
public ActionResult Index()
例:HiddenInputAttribute类,表示一个特性,该特性用于指示是否应将属性值或字段值呈现为隐藏 input 元素
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class HiddenInputAttribute : Attribute
[HiddenInput]
public string zhanshi { get; set; } //只隐藏了Input,但是label还是显示了zhanshi
[HiddenInput(DisplayValue=false)] //只生了 input hidden zhanshi2 没显示
public string zhanshi2 { get; set; }
当DisplayValue设置为false时候,只为zhangshi2属性生成了一个 <input type=”hidden” name=”zhangshi2” value>元素。但是zhangshi生成了2个元素,一个displayName元素,照常显示,而input元素则隐藏了。
2)System.ComponentModel.DataAnnotations 空间下的特性类
AssociationAttribute 指定某个实体成员表示某种数据关系,如外键关系。
DataTypeAttribute 指定要与数据字段关联的附加类型的名称。 为属性呈现html时候才有用,数据验证的时候不使用这个,你懂的。
DisplayColumnAttribute 将所引用的表中显示的列指定为外键列。
DisplayFormatAttribute 指定 ASP.NET 动态数据如何显示数据字段以及如何设置数据字段的格式。
EditableAttribute 指示数据字段是否可编辑。
EnumDataTypeAttribute 使 .NET Framework 枚举能够映射到数据列。
FilterUIHintAttribute 表示一个特性,该特性用于指定列的筛选行为。
KeyAttribute 表示一个或多个用于唯一标识实体的属性。
MetadataTypeAttribute 指定要与数据模型类关联的元数据类。
RangeAttribute 指定数据字段值的数值范围约束。
RegularExpressionAttribute 指定 ASP.NET 动态数据中的数据字段值必须与指定的正则表达式匹配。
RequiredAttribute 指定需要数据字段值。
ScaffoldColumnAttribute 指定类或数据列是否使用基架。
ScaffoldTableAttribute 指定类或数据表是否使用基架。
StringLengthAttribute 指定数据字段中允许的最小和最大字符长度。
TimestampAttribute 将列的数据类型指定为行版本。
UIHintAttribute 指定动态数据用来显示数据字段的模板或用户控件。
ValidationAttribute 作为所有验证特性的基类。
下面例子针对DataTypeAttribute进行应用
[DataType(DataType.EmailAddress)] //表是货币值
[Display(Order=1)] //html显示的顺序
public string lastname { get; set; }
view:@Html.DisplayForModel()
呈现出的html代码和外观: 点击邮箱名称就可以直接调用默认操作系统的邮件系统。
<div class="display-field"><a href="mailto:sdfsd@sina.com">sdfsd@sina.com</a></div>,即使model中lastname设置成不正确的email格式,也会展现出。
html代码:<a href="mailto:sdfsd">sdfsd</a>
Date 表示日期值。
Time 表示时间值。
Duration 表示对象存在的一段连续时间。
PhoneNumber 表示电话号码值。
Currency 表示货币值。
Text 表示所显示的文本。
Html 表示一个 HTML 文件。
MultilineText 表示多行文本。
EmailAddress 表示电子邮件地址。
Password 表示密码值。
Url 表示 URL 值。
ImageUrl 表示图像的 URL。
注意DataType不能重复对同一个属性使用
例子:
[DataType(DataType.DateTime)] //表是货币值
[Display(Order=1)]
public string lastname { get; set; }
lastname设置为 DateTime.Now.ToLongDateString() =2014年4月1日
如何lastname能转换为DateTime就转换,不能转换就按照原来的显示。
上面就是常用的特性,有些特性是用来辅助将属性或者元素呈现出来,有些还带有验证功能。
自定义模版,比如自定义控件,当某个属性拥有了[UIHint("模版名称")]特性,那么就会按照新的方式展示,不会按照默认的方式执行。
例:model:public string name{get;set;}
view:@html.DisplayforModel()
最终为属性name呈现的html元素为input输入框,这个input输入框就是默认的模版,当知道是string或者Int类型后,再没设置其他模版的前提下,选择默认的input元素。
如果我不想让对string类型,在呈现的时候显示input输入框元素,那么我们可以自定义模版,然后在属性上应用[UIHint(自定义的新模版)]就可以不使用默认的input元素了。
现在开始动手,假设将string类型的属性呈现出另外的效果,比如display时候显示 2个输入,编辑时候显示2个输入框。
先新建2个文件夹,注意文件夹名称必须是分别为DisplayTemplates,EditorTemplates
然后在文件夹里建立2个相同名称的view视图 Data.cshtml。Data就是新定义的模版名称。
代码分别如下
DisplayTemplates/Data.cshtml
<script type="text/javascript">$(function () {$(".datepicker").datepicker({ "dateFormat": "yy-mm-dd" })});</script>@Html.TextBox("", String.Format("{0:yyyy-MM-dd}", ViewData.TemplateInfo.FormattedModelValue), new { @class = "datepicker" })
EditTemplates/Data.cshtml
@Html.DropDownList("",MvcApplication1.Sample_ModelMeta.DropDownListMenu.年齡選項(),"请选择年龄")
model中设置模版
public class user{[UIHint("Data")]public string lastname { get; set; }}
view: 第一个是编辑,第2个是展示
@Html.DisplayFor(model=>model.lastname,"Data")@Html.EditorFor(model=>model.lastname,"Data")
action中设置lastname=DateTime.Now
html代码:
<div>显示:<input id="lastname" name="lastname" type="text" value="2014/4/2"><script type="text/javascript">$(function () {$(".datepicker").datepicker({ "dateFormat": "yy-mm-dd" })});</script>编辑:<input class="datepicker hasDatepicker" id="lastname" name="lastname" type="text" value="2014/4/2"></div>
效果图: 使用EditorFor呈现的是一个输入框,当你点击后可以选择时间。这个时间控件是Jquery Ui中的,所以view要引用jquery.ui.cs
MVC查找模版的路径先为当前controller同名的view文件夹下查找,找不到了,再最后是shared文件夹中查找,如果没找到任何模版,则还是按照默认显示)
元数据定制,就是在属性上添加自定义特性,可以设置元数据。 例如 自定义[displayText]特性
至于如何自定义,首先我们要查看系统默认存在的一些特性的类的结构
public class DisplayTextAttribute:Attribute,IMetadataAware
继承Attribute类和IMetadataAware接口,实现接口中的OnMetadatAware接口
public void OnMetadataCreated(ModelMetadata metadata){this.DisplayName=this.DisplayName??(metadata.PropertyName??metadata.ModelType.Name);if(null==this.ResourceType){metadata.DisplayName=this.DisplayName;return ;}PropertyInfo property=this.ResourceType.GetProperty(this.DisplayName, BindingFlags.NonPublic|BindingFlags.Public| BindingFlags.Static);//PropertyInfo property = metadata.ModelType.GetProperty(this.DisplayName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);metadata.DisplayName = "我把所有列名都改了";//property.GetValue(null, null).ToString();metadata.TemplateHint="MultilineText";}
在方法中,我们可以设置模型元数据的信息 ,比如此处我将DisplayName都设置成了“xxx”,并设置了模版 为MultilineText。
[DisplayText]public string Name { get; set; }
效果展示:@html.displayForModel() 为Name呈现一个 label内容为“我把所有列名都改了”,而且输入框显示的是多行模式。
元数据提供系统,ASP.net提供了一个可插拔的模型元数据提供系统DataAnAnnotationModelMetaProvder,可插拔的意思就是可以自定义然后替换掉默认的元数据提供系统。
若要自定义,请继承ModelMetadataProvider类,实现3个方法。
下面是部分自定义元数据提供系统CustomerMetaProvider类
namespace MvcApplication1.CustomerMetaProvider{public class CustomerMetadataProvider : ModelMetadataProvider{public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType){throw new NotImplementedException();}public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName){throw new NotImplementedException();}public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType){throw new NotImplementedException();}}public class Contact{public string FirstName { get; set; }public string LastName { get; set; }public string EmailAddress { get; set; }}}
应用上面的提供系统,要在Global.asax.cs 的Application_Start中加上一句 ModelMetadataProviders.Current = new CustomModelMetadataProviderWithConfig();
这样就要MVC项目中当模型绑定和为属性呈现元素时候都要从上面自定义的元数据提供系统提供ModelMetaData,所以上面的3个方法一定要重写。
本例子没实现这3个方法,待补充!
至此,模型元数据的意义,模型元数据定制,自定义模型元数据提供系统,以及自定义html模版 都研究完成。
再加上签名的 模型绑定器,自定义验证特性,自定义验证特性的客户端验证都已完成。
目前还剩下 自定义值提供器 和 自定义视图模版和视图结构。
MVC3.0学习笔记之元模型元数据ModelMetaData以及模型元数据提供系统的更多相关文章
- ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供
一. 元数据描述类型ModelMetadata 模型元数据是对Model的描述信息,在ASP.NET MVC框架中有非常重要的作用,在模型绑定,模型验证,模型呈现等许多地方都有它的身影.描述Model ...
- DirectX 总结和DirectX 9.0 学习笔记
转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...
- 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移
不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...
- vue2.0学习笔记之路由(二)路由嵌套+动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue2.0学习笔记之路由(二)路由嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- hdcms v5.7.0学习笔记
hdcms v5.7.0学习笔记 https://note.youdao.com/ynoteshare1/index.html?id=c404d63ac910eb15a440452f73d6a6db& ...
- dhtmlxgrid v3.0学习笔记
dhtmlxgrid v3.0学习笔记 分类: dhtmlx JavaScript2012-01-31 15:41 1744人阅读 评论(0) 收藏 举报 stylesheetdatecalendar ...
- OAuth 2.0学习笔记
文章目录 OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动. OAuth在"客户端&quo ...
- CTR学习笔记&代码实现3-深度ctr模型 FNN->PNN->DeepFM
这一节我们总结FM三兄弟FNN/PNN/DeepFM,由远及近,从最初把FM得到的隐向量和权重作为神经网络输入的FNN,到把向量内/外积从预训练直接迁移到神经网络中的PNN,再到参考wide& ...
随机推荐
- android: 服务的生命周期
9.4 服务的生命周期 之前章节我们学习过了活动以及碎片的生命周期.类似地,服务也有自己的生命周期, 前面我们使用到的 onCreate().onStartCommand().onBind()和 ...
- ZPL打印中文信息
博客来源:http://www.cnblogs.com/Geton/p/3595312.html 相信各位在实际的项目中,需要开发打条码模块的也会有不少,很多同行肯定也一直觉得斑马打印机很不错,但是Z ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)篇 二.本篇目标: l 说说关于cocos2dx手机分辨率适配 l 对前一篇完成的塔防游戏原型进 ...
- Tomcat远程调试
1.如果tomcat在Windows下 打开%CATALINE_HOME%/bin下的文件catalina.bat,加入下面这行: set CATALINA_OPTS=-server -Xdebug ...
- 推荐算法——距离算法
本文内容 用户评分表 曼哈顿(Manhattan)距离 欧式(Euclidean)距离 余弦相似度(cos simliarity) 推荐算法以及数据挖掘算法,计算"距离"是必须的~ ...
- Andriod调用http请求
// 新建HttpPost对象 HttpPost httpPost = new HttpPost( "http://180.153.1.1:8080/mybankGateway/gatewa ...
- 错误名称:EntityCommandExecutionException
错误名称:EntityCommandExecutionException 错误时间:2015/9/22 11:13:34 错误消息:执行命令定义时出错.有关详细信息,请参阅内部异常. 堆栈信息: 在 ...
- ubuntu(Mint-17)修改dns
国内默认dns常被劫持,所以需要修改: $ sudo vi /etc/network/interfaces 在下面添加一行: dns-nameservers 8.8.8.8 8.8.4.4 然后,网上 ...
- LCLFramework框架之IOC
我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 借助于"第三方"实现具有依赖关系的对象之间的解 ...
- WebRTC is for Losers:WebRTC是输家
该文章是引述,仅代表作者Dave Michels观点 WebRTC is for Losers WebRTC technology has fallen short on many of its pr ...