这是我的发展要求, 我的标签值存储在数据库中,我仍然希望以声明的方式使用数据注释,这是为了使我的模型更具可读性. 这是我的方法, 我决定编写自定义DisplayNameAttribute,其中我的模型
我的标签值存储在数据库中,我仍然希望以声明的方式使用数据注释,这是为了使我的模型更具可读性.
这是我的方法,
我决定编写自定义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; }
但问题是,类型集合为我提供了所有模型的条目(用户至少访问过一次).并且没有任何线索可以知道,目前正在行动!
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; } }
> containerType = MyViewModel
> modelType = MyPropertyType
> propertyName = PropertyName
然后注册提供者(global.asax或其他):
ModelMetadataProviders.Current = new LocalizedModelMetadataProvider();
另外你可以看一下ModelMetadata它还有一些你可能想要在未来改变的东西.