Asp.net mvc 3 在“自定义显示名称”属性中检索模型名称
这是我的发展要求, 我的标签值存储在数据库中,我仍然希望以声明方式使用数据注释,这是为了使我的模型更具可读性 这是我的方法 我决定编写自定义DisplayNameAttribute,其中模型提供的默认值将被从数据库检索到的值覆盖 这是在模型中定义的属性Asp.net mvc 3 在“自定义显示名称”属性中检索模型名称,asp.net-mvc-3,data-annotations,modelmetadataprovider,displayname-attribute,Asp.net Mvc 3,Data Annotations,Modelmetadataprovider,Displayname Attribute,这是我的发展要求, 我的标签值存储在数据库中,我仍然希望以声明方式使用数据注释,这是为了使我的模型更具可读性 这是我的方法 我决定编写自定义DisplayNameAttribute,其中模型提供的默认值将被从数据库检索到的值覆盖 这是在模型中定义的属性 [CustomDisplay(Name: "First Name")] [CustomRequired(ErrorMessage: "{0} is required")] public String FirstName {
[CustomDisplay(Name: "First Name")]
[CustomRequired(ErrorMessage: "{0} is required")]
public String FirstName { get; set; }
这是自定义显示名称属性类
public class CustomDisplayAttribute : DisplayNameAttribute
{
private string _defaultName;
private string _displayName;
public CustomDisplayAttribute(string Name)
{
_defaultName = Name;
}
public override string DisplayName
{
get
{
if (String.IsNullOrEmpty(_displayName))
{
_displayName = DAO.RetrieveValue(**ModelName**, _defaultName);
}
return _displayName;
}
}
}
现在,您可以在上面的代码中看到,ModelName是我需要的东西,但我没有
在调试过程中,我深入研究了ModelMetadataProviders.Current,可以看到当前模型的可用性。但是,由于它是非公共静态成员的一部分,我无法通过代码访问它
我编写了下面的方法,通过反射检索模型名
private static string GetModelName()
{
var modelName = String.Empty;
FieldInfo info = typeof(CachedAssociatedMetadataProvider<CachedDataAnnotationsModelMetadata>)
.GetField("_typeIds", BindingFlags.NonPublic | BindingFlags.Static);
var types = (ConcurrentDictionary<Type, string>)info.GetValue(null);
modelName = types.FirstOrDefault().Key.Name;
return modelName;
}
私有静态字符串GetModelName()
{
var modelName=String.Empty;
FieldInfo=typeof(CachedAssociatedMetadataProvider)
.GetField(“_typeid”,BindingFlags.NonPublic | BindingFlags.Static);
变量类型=(ConcurrentDictionary)info.GetValue(null);
modelName=types.FirstOrDefault().Key.Name;
返回modelName;
}
但问题是,types集合为所有模型(用户至少访问一次)提供了me条目。而且目前还没有任何线索可以知道,目前正在行动中
IMHO属性不应用于进行数据库调用。属性应用于向类/属性等添加元数据
因此,如果您愿意将代码更改为更像Microsoft MVC体系结构,那么您将拥有自定义属性和自定义ModelMetadataProvider:
public class CustomDisplayAttribute : Attribute
{
public CustomDisplayAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class DatabaseModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
public DatabaseModelMetadataProvider()
{
}
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 displayAttribute = containerType == null
? null as CustomDisplayAttribute
: containerType.GetProperty(propertyName)
.GetCustomAttributes(false)
.OfType<CustomDisplayAttribute>()
.FirstOrDefault();
if (displayAttribute != null)
{
var displayValue = DAO.RetrieveValue(containerType.ToString(), displayAttribute.Name)
metadata.DisplayName = displayValue;
}
return metadata;
}
}
然后是一个新的ModelMetadataProvider:
public class CustomDisplayAttribute : Attribute
{
public CustomDisplayAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class DatabaseModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
public DatabaseModelMetadataProvider()
{
}
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 displayAttribute = containerType == null
? null as CustomDisplayAttribute
: containerType.GetProperty(propertyName)
.GetCustomAttributes(false)
.OfType<CustomDisplayAttribute>()
.FirstOrDefault();
if (displayAttribute != null)
{
var displayValue = DAO.RetrieveValue(containerType.ToString(), displayAttribute.Name)
metadata.DisplayName = displayValue;
}
return metadata;
}
}
- containerType=MyViewModel
- modelType=MyPropertyType
- propertyName=propertyName