【问题标题】:Create custom display attribute using or inherits DisplayAttribute in ASP.NET MVC在 ASP.NET MVC 中使用或继承 DisplayAttribute 创建自定义显示属性
【发布时间】:2013-12-09 07:45:15
【问题描述】:

我想将DisplayAttributeName 属性一起使用。

问题是类是sealed,我不能继承它来覆盖一些方法。

我为什么要这个?

我想传递一些代码,以便将字符串转换为 Name 属性。并为语言添加一个属性。

类似:

[MyDisplay(Code = TRANSLATION_CODE, Language = "FR-FR")]
public string Fr { get; set; }

在 MyDisplayAttribute 中,我想做这样的事情:

public class MyDisplayAttribute: DisplayAttribute // it won't work the inherits
{
     public int Code { get; set; }
     public string Language { get; set; }

    // somewhere, I don't know what method
    // I want to assing `Name = GetTranslation(Code, Language);`
}

还有其他方法吗?


更新

我也试过这个:

public class MyDisplayAttribute : DisplayNameAttribute
   {
      private int _code;
      private string _language;

      public MyDisplayAttribute( int code, string language )
         : base( language )
      {
         _code = code;
         _language = language;
      }

      public override string DisplayName
      {
         get
         {
            // here come LanguageTranslatorManager
            if ( _code == 1 && _language == "en" ) {
               return "test";
            }

            return base.DisplayName;
         }
      }
   }

在模型中:

  [MyDisplay( 1, "en" )]
  public string Test
  {
     get;
     set;
  }

我希望在视图中显示test,但没有! 我的错在哪里?

【问题讨论】:

  • 它不会覆盖DisplayNameAttribute 的功能。它确实返回了预期值,但没有将其绑定到元数据。您需要显式覆盖模型元数据中的值。
  • 由于你的问题是2年前的问题,你找到解决办法了吗?
  • @ChristianGollhardt:不幸的是,我创建了自定义属性,因为 DisplayNameAttribute 是密封的,无法继承。

标签: c# asp.net-mvc


【解决方案1】:

要为您的属性设置特定的显示名称,您需要设置元数据属性DisplayName。如果您需要编写自定义属性,则需要确保创建自定义元数据提供程序。在里面你需要根据提供的值设置你的属性的DisplayName

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
          Type containerType, Func<object> modelAccessor, 
          Type modelType, string propertyName)
    { 
         var modelMetadata = base.CreateMetadata(attributes, containerType, 
                 modelAccessor, modelType, propertyName);

         if (attributes.OfType<MyDisplay>().ToList().Count > 0)
         {
              modelMetadata.DisplayName = GetValueFromLocalizationAttribute(attributes.OfType<MyDisplay>().ToList()[0]);
         }

         return modelMetadata;
    }

    private string GetValueFromLocalizationAttribute(MyDisplay attribute)
    {
          return computedValueBasedOnCodeAndLanguage;
    }
}

【讨论】:

  • 这也适用于 WinForms 吗? DataAnnotationsModelMetadataProvider 在 System.Web.ModelBinding
  • @qub1n,我不确定。您必须引用所有涉及的命名空间,然后必须确保显式调用 MetadataProvider。编写自己的轻量级“MetadataProvider”可能会更容易。
【解决方案2】:

你做错了。 DisplayAttribute 已经支持使用内置 .net 国际化的“翻译”

 [Display(Name = "property_name", ResourceType = typeof(MyResources))]

仅当这还不够时,您才应该创建自己的属性,而不是从 Display 派生。

编辑:

DisplayAttribute 是一个密封类,所以没有办法继承它。

【讨论】:

  • 不,我想使用我的自定义翻译资源,而不是来自 .net
  • 我试图做和 OP 一样的事情。我的目标是扩展 DisplayAttribute,这样我就可以将 ResourceType 的东西放在我的 LocalizedDisplayAttribute 中,而不必一直在我的模型中定义它。
猜你喜欢
  • 2010-11-12
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多