模型元数据ModelMetaData是MVC中很重要的概念,它包括但不仅限于 模型的类型,模型包含了哪些属性,属性都是什么类型的,属性上都有什么特性。
ASP.NET MVC3.0 提供了默认的模型元数据 DataAnnotationsModelMetadata 继承自ModelMetadata(另外系统提供了默认的模型元数据提供器DataAnnotationsModelMetadataProvider)
public class DataAnnotationsModelMetadata : ModelMetadata
它的构造函数如下
public DataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Func
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="名称 字段是必需的。" >
$(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模版 都研究完成。
再加上签名的 模型绑定器,自定义验证特性,自定义验证特性的客户端验证都已完成。
目前还剩下 自定义值提供器 和 自定义视图模版和视图结构。