我想在MVC视图中访问DataAnnotation
的{{1}}。
例如,假设我的一个模型属性就像
GroupName
现在,我如何访问视图中的[Display(Order = 1, GroupName= "Passport Detail", Name = "Passport #")]
[Required()]
[StringLength(20)]
public string PassportNo { get; set; }
?
我希望在 MVC 中实现类似this的内容。
答案 0 :(得分:2)
我也在研究这个问题,看起来你必须为一个属性做很多代码,而这个属性应该就在那里......对吧?
我不是必须扩展当前逻辑,而是使用AdditionalValuesAttribute来定义我自己的“GroupName”。当然,你可以通过扩展它来获得所有“花式裤子”,但它基本上是这样的:
if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("GroupName")) {
var groupName = ViewData.ModelMetadata.AdditionalValues["GroupName"].ToString();
}
答案 1 :(得分:1)
我找到了解决方案。
我们可以通过使用DataAnnotationsModelMetadataProvider来实现这一目标
例如
public class MetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType, Func<object> modelAccessor,
Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
var disp = attributes.OfType<DisplayAttribute>().FirstOrDefault();
if (disp != null)
{
if (disp.GroupName != null)
metadata.AdditionalValues.Add("GroupName", disp.GroupName);
}
return metadata;
}
}
在mvc视图中,我们可以像往常一样使用AdditionalValues。
答案 2 :(得分:0)
好吧,我没看到MVC使用它。 DataAnnotations并不是MVC的一部分,因此不能使用所有道具。如果你想使用它,我会说你需要创建一个可以创建这些组的HTML帮助器。
好的,我想我看到了你想要的东西......你想让它为你自动模板化。只需使用EditorTemplates。 http://www.codecapers.com/post/Display-and-Editor-Templates-in-ASPNET-MVC-2.aspx
答案 3 :(得分:0)
怎么样!!!必须工作:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
namespace System.Web.Mvc
{
public static class DisplayGroup
{
public static MvcHtmlString DisplayGroupName(this HtmlHelper helper, string groupName)
{
return MvcHtmlString.Create(groupName);
}
public static MvcHtmlString DisplayGroupNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
var type = typeof(TModel);
PropertyInfo propertyInfo = null;
var member = (MemberExpression)expression.Body;
var property = (PropertyInfo)member.Member;
var name = property.Name;
var metadataTypeInfo = type.GetCustomAttribute<MetadataTypeAttribute>();
if (metadataTypeInfo != null)
{
var metadataType = metadataTypeInfo.MetadataClassType;
propertyInfo = metadataType.GetProperties().Where(x => x.Name == name).FirstOrDefault();
if (propertyInfo == null)
{
propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
}
}
else
{
propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault();
}
string output = "";
var dattr = propertyInfo.GetCustomAttribute<DisplayAttribute>();
if (dattr != null)
{
if (dattr.GroupName == null)
{
output = propertyInfo.Name;
}
else
{
output = dattr.GroupName;
}
}
else
{
output = propertyInfo.Name;
}
return MvcHtmlString.Create(output);
}
}
}
public class MyModel
{
[Display(Name = "Number",GroupName="Invoice")]
string InvNo { get; set; }
}
然后简单地写:
@Html.DisplayGroupNameFor(x => x.InvNo)
注意:
NameSpace应该是:System.Web.Mvc
更新
很酷的是,如果您为dataAnnotation定义了MetaDataType
类,那么这也将按预期工作。