4

这里是我的发展要求,检索模型名称

我的标签值存储在数据库中,我仍然想使用数据注释以声明的方式,这是为了让我的模型更具可读性。

这里是我的方法,

我决定编写自定义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,并可以看到当前模型的可用性。但是,由于它是非公共静态成员的一部分,我无法通过我的代码访问它。

enter image description here

我已经写了下面的方法来检索通过反射的型号名称,

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; 
} 

但问题是,该类型集合为我提供了所有的模型项(至少访问过一次由用户)。而且目前还没有线索知道,目前正在实施中!

enter image description here

回答

0

恕我直言属性应该用来做数据库调用。属性应该用于向类/属性等添加元数据...

所以,如果你愿意改变你的代码更像MVC的微软架构,那么你会有你的自定义属性和一个自定义的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的=属性名

然后注册商(Global.asax中或其他):

ModelMetadataProviders.Current = new LocalizedModelMetadataProvider(); 

您也可以看看在ModelMetadata它有一些其他的东西你可能会在未来改变。