7

I want to use DisplayAttribute with Name property.

The problem is that class is sealed and I cannot inherits it to override some methods.

Why I want this ?

I want to pass some a code in order to translate strings to Name property. And add one property for language.

Something like:

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

And inside MyDisplayAttribute, I want to do like:

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

There is another way to do that ?


UPDATE

I tried also this:

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

and in model:

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

I'm expecting to display test in view, but doesn't ! Where is my mistake ?

Snake Eyes
  • 16,287
  • 34
  • 113
  • 221
  • It doesn't overwrite the functionality of the `DisplayNameAttribute`. It does return the expected value but it's doesn't bind it to the metadata. You need to explicitly overwrite the value in the model metadata. – Andrei V Dec 09 '13 at 08:12
  • Since your question is 2 years ago, did you find a solution to it? – Christian Gollhardt Nov 24 '15 at 21:10
  • @ChristianGollhardt: Unfortunately not, I created my custom attribute because DisplayNameAttribute is sealed and cannot be inherited. – Snake Eyes Nov 27 '15 at 06:42

2 Answers2

4

In order to set a specific display name for your property, you need to set the metadata property DisplayName. If you need to write custom attributes, you need to make sure that you create a custom metadata provider. Inside you need to set the DisplayName of your property, based on the values provided.

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;
    }
}
Andrei V
  • 7,306
  • 6
  • 44
  • 64
  • Does this works for WinForms as well? DataAnnotationsModelMetadataProvider is in System.Web.ModelBinding – Tomas Kubes Mar 23 '18 at 14:16
  • @qub1n, I'm not sure. You'd have to reference all the namespaces involved and then you'd have to make sure that the MetadataProvider is explicitly called. It might just be easier to write your own, lightweight, "MetadataProvider". – Andrei V Mar 23 '18 at 14:27
3

You are doing it wrong. The DisplayAttribute already supports 'translations' using the built-in .net internationalization

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

Only if that's not enough you should create your own attribute, but not deriving from Display.

Edit:

The DisplayAttribute is a sealed class, so there is no way to inherit from it.

tomrozb
  • 25,773
  • 31
  • 101
  • 122
MikeSW
  • 16,140
  • 3
  • 39
  • 53
  • No, I want to use my custom translation resources, not from .net – Snake Eyes Dec 09 '13 at 08:00
  • 4
    I was trying to do the same as the OP. My goal was to extend DisplayAttribute so I could put the ResourceType stuff in my LocalizedDisplayAttribute and not have to define it all the time in my models. – Snekse May 09 '14 at 20:38