Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 在“自定义显示名称”属性中检索模型名称_Asp.net Mvc 3_Data Annotations_Modelmetadataprovider_Displayname Attribute - Fatal编程技术网

Asp.net mvc 3 在“自定义显示名称”属性中检索模型名称

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 {

这是我的发展要求,

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

这是我的方法

我决定编写自定义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;
}
私有静态字符串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
然后注册提供商(global.asax或其他任何内容):

此外,您还可以看一看,它有一些其他的东西,您可能希望在未来改变