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它有一些其他的東西你可能會在未來改變。