这是我的开发要求,
我的标签值存储在数据库中,我仍然希望以声明的方式使用数据注释,这是为了使我的模型更具可读性。
这是我的方法,
我决定编写自定义DisplayNameAttribute,其中我的模型提供的默认值将被从数据库中检索的值覆盖。
这是模型中定义的属性
[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;
}
但问题是,types集合为我提供了所有模型的条目(用户至少访问过一次)。并且没有任何线索可以知道,目前正在行动!!
答案 0 :(得分:0)
IMHO属性应该不用于进行数据库调用。属性应该用于向类/属性等添加元数据......
因此,如果您愿意将代码更改为更像MVC的Microsoft体系结构,那么您将拥有自定义属性和自定义ModelMetadataProvider:
public class CustomDisplayAttribute : Attribute
{
public CustomDisplayAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
然后是一个新的ModelMetadataProvider:
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;
}
}
其中
public class MyViewModel
{
public MyPropertyType PropertyName { get; set; }
}
然后注册提供者(global.asax或其他):
ModelMetadataProviders.Current = new LocalizedModelMetadataProvider();
此外,您可以查看ModelMetadata它还有一些您可能希望在将来更改的其他内容。