模型元数据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空间下的

AcceptVerbsAttributeActionFilterAttributeActionNameAttributeAsyncTimeoutAttributeAuthorizeAttributeBindAttribute

HiddenInputAttribute 

ActionFilterAttribute  表示所有操作-筛选器特性的基类

HttpDeleteAttribute 类,表示一个特性,该特性用于限制操作方法,以便该方法仅处理 HTTP DELETE 请求

HttpGetAttributeHttpPostAttribute 表示特性,用于限制操作方法,仅限处理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以及模型元数据提供系统的更多相关文章

  1. ASP.NET MVC5学习笔记之Action参数模型绑定之模型元数据和元数据提供

    一. 元数据描述类型ModelMetadata 模型元数据是对Model的描述信息,在ASP.NET MVC框架中有非常重要的作用,在模型绑定,模型验证,模型呈现等许多地方都有它的身影.描述Model ...

  2. DirectX 总结和DirectX 9.0 学习笔记

    转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...

  3. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  4. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. hdcms v5.7.0学习笔记

    hdcms v5.7.0学习笔记 https://note.youdao.com/ynoteshare1/index.html?id=c404d63ac910eb15a440452f73d6a6db& ...

  7. dhtmlxgrid v3.0学习笔记

    dhtmlxgrid v3.0学习笔记 分类: dhtmlx JavaScript2012-01-31 15:41 1744人阅读 评论(0) 收藏 举报 stylesheetdatecalendar ...

  8. OAuth 2.0学习笔记

    文章目录 OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动. OAuth在"客户端&quo ...

  9. CTR学习笔记&代码实现3-深度ctr模型 FNN->PNN->DeepFM

    这一节我们总结FM三兄弟FNN/PNN/DeepFM,由远及近,从最初把FM得到的隐向量和权重作为神经网络输入的FNN,到把向量内/外积从预训练直接迁移到神经网络中的PNN,再到参考wide& ...

随机推荐

  1. 【Android 】Service 全面总结

    1.Service的种类 按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...

  2. Windows 10 Java环境变量配置

    Win10下 Java环境变量配置 首先,你应该已经安装了 Java 的 JDK 了(如果没有安装JDK,请跳转到此网址:http://www.oracle.com/technetwork/java/ ...

  3. WordPress安装使用问题记录

    本文记录在使用WordPress过程中的问题和解决. 安装 比较顺利没有问题,具体如下(CentOS 6.5,DO的CentOS7 image里默认的yum源没有mysql-serve比较奇怪r): ...

  4. How to get blob data using javascript XmlHttpRequest by sync

    Tested: Firefox 33+ OK Chrome 38+ OK IE 6 -- IE 10 Failed Thanks to 阮一峰's blog: http://www.ruanyifen ...

  5. Windows下如何枚举所有进程

    要编写一个类似于 Windows 任务管理器的软件,首先遇到的问题是如何实现枚举所有进程.暂且不考虑进入核心态去查隐藏进程一类的,下面提供几种方法.请注意每种方法的使用局限,比如使用这些 API 所需 ...

  6. UIScrollView offset in UINavigationController

    转:UIScrollView offset in UINavigationController 通过设置viewCtronller的 self.automaticallyAdjustsScrollVi ...

  7. 初识React,Virutal DOM, State以及生命周期

    这是React分类下的第一篇文章,是在了解了一些基本面后,看Tyler文章,边看边理解边写的. React可以看做是MVC中的V,关注的是视图层.React的组件就像Angular的Directive ...

  8. Tomcat远程调试

    1.如果tomcat在Windows下 打开%CATALINE_HOME%/bin下的文件catalina.bat,加入下面这行: set CATALINA_OPTS=-server -Xdebug ...

  9. iOS 同一设备内的应用之间资源共享的实现

    我们都知道,iOS为安全考虑,各应用只能使用其自已的应用沙盒内的存储空间,各应用之间是不能互相访问彼此的沙盒空间的. 另外,iOS设备都没有外置存储卡,这样,象 Android 设备间共同访问外置存储 ...

  10. embarcadero radstudio xe5 正式版 下载地址

    http://altd.embarcadero.com/download/radstudio/xe5/delphicbuilder_xe5_win.iso