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 ?