-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Easy access to Enum Display(Name) #4215
Comments
You need to create your own helper for getting the DisplayName attribute of an enum value. Take a look at this: |
Ok, I dealt with that by using suggested extension method. Thanks. However still I think that this should be simplified and embbeded into razor sytax as displaying Enum Display Name is quite common.
|
I would suggest that's not the right way to go about it. Add your own meta data provider to the services.AddMvc(options =>
{
options.ModelMetadataDetailsProviders.Add(new MyMetaDataProvider());
}); Here is an example of a public class HumanizerMetaDataProvider : IDisplayMetadataProvider
{
public void GetDisplayMetadata(DisplayMetadataProviderContext context)
{
if (IsTransformRequired(context.DisplayMetadata, context.PropertyAttributes))
{
context.DisplayMetadata.DisplayName = () => context.Key.Name.Humanize();
}
}
private static bool IsTransformRequired(DisplayMetadata modelMetadata, IReadOnlyList<object> propertyAttributes)
{
if (propertyAttributes == null)
return false;
if (propertyAttributes.OfType<DisplayNameAttribute>().Any())
return false;
if (propertyAttributes.OfType<DisplayAttribute>().Any())
return false;
return true;
}
} Basically, we're using |
Thanks for the awesome and helpful example @ctolkien. |
@Eilon Is this really a bug instead of an enhancement? |
Done? |
Don't know where to post my question so I'm doing it here hoping someone will see it and be able to give a small explanation of why things are like they are. I was trying to localize enum display attributes and it never worked even if using the recommended approach of setting a SharedResource class for all data annotations localization. I was wondering why it didn't work and tried to figure it out by debugging from source. From what I found, it seems like the enumLocalizer is not using the SharedResource for localization and I'd like to know why it is as such. Especially, I was looking here and saw that it was using a localizer built using the underlyingType. Wouldn't it be a good option to use the same SharedResource localizer? Even if it's an enum, the display attribute is still a display attribute and it is confusing (to me at least) when I read that I can make all data annotations localization check in a shared location for localized strings by doing so: Thanks in advance |
I agree with the previous comment, it seems like the DataAnnotationsMetadataProvider uses the IStringLocalizerFactory.Create() directly rather the DataAnnotationLocalizerProvider specified in options. This looks like a bug to me, or at least there should be some kind of provider you can specify for enums so that you can use a shared resource for them as well. As for a workaround, I created a custom IStringLocalizerFactory by extending the existing ResourceManagerStringLocalizerFactory, not sure if this is the best way to go about it, but it seems to work for now: public class SharedResourceLocalizationFactory : ResourceManagerStringLocalizerFactory
{
public SharedResourceLocalizationFactory(IOptions<LocalizationOptions> localizationOptions, ILoggerFactory loggerFactory) : base(localizationOptions, loggerFactory)
{
_loggerFactory = loggerFactory;
}
private readonly ILoggerFactory _loggerFactory;
private readonly IResourceNamesCache _resourceNamesCache = new ResourceNamesCache();
protected override ResourceManagerStringLocalizer CreateResourceManagerStringLocalizer(Assembly assembly, string baseName)
{
var typeInfo = typeof(SharedResource).GetTypeInfo();
baseName = GetResourcePrefix(typeInfo);
assembly = typeInfo.Assembly;
return new ResourceManagerStringLocalizer(
new ResourceManager(baseName, assembly),
assembly,
baseName,
_resourceNamesCache,
_loggerFactory.CreateLogger<ResourceManagerStringLocalizer>());
}
} In Startup.ConfigureServices() services.AddSingleton<IStringLocalizerFactory, SharedResourceLocalizationFactory>(); |
Let's consider the following enum type:
If I use it in my model I can easily display conveinient drop down list based on Display Name attribute using the following statement:
However If I want to display the selected value in my details view using:
I get BankTransfer, Cash or Other instead of Display Name attribute.
Is it possiible to get easy access to Display Name attribute in views?
The text was updated successfully, but these errors were encountered: