Asp.Net MVC2中扩展ModelMetadata的DescriptionAttribute。
在MVC2中默认并没有实现DescriptionAttribute(虽然可以找到这个属性,通过阅读MVC源码,发现并没有实现方法),这很不方便,特别是我们使用EditorForModel的时候,我们需要对字段进行简要的介绍,下面来扩展这个属性。
新建类 DescriptionMetadataProvider
然后重写DataAnnotationsModelMetadataProvider的CreateMetadata方法:
public class DescriptionMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
List<System.Attribute> attributeList = new List<System.Attribute>(attributes);
DataAnnotationsModelMetadata result = (DataAnnotationsModelMetadata)base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
DescriptionAttribute descriptionAttribute = attributeList.OfType<DescriptionAttribute>().FirstOrDefault();
if (descriptionAttribute != null)
{
result.Description = descriptionAttribute.Description;
}
return result;
}
}
{
protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
List<System.Attribute> attributeList = new List<System.Attribute>(attributes);
DataAnnotationsModelMetadata result = (DataAnnotationsModelMetadata)base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
DescriptionAttribute descriptionAttribute = attributeList.OfType<DescriptionAttribute>().FirstOrDefault();
if (descriptionAttribute != null)
{
result.Description = descriptionAttribute.Description;
}
return result;
}
}
接下来在Global.asax的Application_Start()中注册DescriptionMetadataProvider
ModelMetadataProviders.Current = new DescriptionMetadataProvider();
接着你就可以使用如下方进行标注:
[DisplayName("办公地址")]
[Required]
[Description("请填写真实的办公地址")]
public string OfficeAddress { get; set; }
[Required]
[Description("请填写真实的办公地址")]
public string OfficeAddress { get; set; }
来看看实际效果:
MVC2给我们带来了很好的模板机制,给大家提供一个学习地址:
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
而上面扩展这个方法,我们可以这样来设计模板。
在Shared目录中新建EditorTemplates文件夹,添加MVC用户控件Object.ascx,请注意当我们使用<%= Html.EditorForModel() %>方法的时候,MVC会自动寻找Object.ascx,其顺序是
Views=>ControllerName=>EditorTemplates=>Object.ascx
当在对应Controller的View中找不到Object.ascx,那么会继续在Shared=>EditorTemplates文件夹找(还会找对应模板aspx)。
来看看一个简单的Object.ascx
代码
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
<%= ViewData.ModelMetadata.SimpleDisplayText%>
<% }
else { %>
<table class="grid"><thead><tr><th>名 称</th><th>内 容</th><th>信 息</th></tr></thead><tbody>
<% int i = 0;
foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
{
%>
<% if (prop.HideSurroundingHtml)
{ %>
<%= Html.Editor(prop.PropertyName)%>
<% }else { %>
<tr <%= i%2!=0?"class='trRe'" :"" %>><td style=" width:100px;"><% if (!String.IsNullOrEmpty(prop.DisplayName)){ %> <%= prop.DisplayName%> <% } %></td><td style=" text-align:left;"><%= Html.Editor(prop.PropertyName)%> </td><td><%=prop.IsRequired ? "*" : null%><%= Html.ValidationMessage(prop.PropertyName)%><%= prop.Description %></td></tr>
<% } %>
<% i++;
} %> <tr><td colspan="3"><input type="submit" value="提交" /></td></tr>
</tbody></table>
<% } %>
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
<%= ViewData.ModelMetadata.SimpleDisplayText%>
<% }
else { %>
<table class="grid"><thead><tr><th>名 称</th><th>内 容</th><th>信 息</th></tr></thead><tbody>
<% int i = 0;
foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
{
%>
<% if (prop.HideSurroundingHtml)
{ %>
<%= Html.Editor(prop.PropertyName)%>
<% }else { %>
<tr <%= i%2!=0?"class='trRe'" :"" %>><td style=" width:100px;"><% if (!String.IsNullOrEmpty(prop.DisplayName)){ %> <%= prop.DisplayName%> <% } %></td><td style=" text-align:left;"><%= Html.Editor(prop.PropertyName)%> </td><td><%=prop.IsRequired ? "*" : null%><%= Html.ValidationMessage(prop.PropertyName)%><%= prop.Description %></td></tr>
<% } %>
<% i++;
} %> <tr><td colspan="3"><input type="submit" value="提交" /></td></tr>
</tbody></table>
<% } %>
有了这个模板的定义,大家可以尝试使用<%= Html.EditorForModel() %>方法,看看效果有什么不同呢?