Create custom display attribute using or inherits DisplayAttribute in ASP.NET MVC

asp.net-mvc, c#

Solution

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

Problem

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 ?

Original source