0

I am trying to localize the DisplayFormat of several of my view models. I have been able to localize the Display:Name, Required and RegularExpression messages all from a shared resource file in a separate project.

In addition, I have been able to localize my razor views and any messages generated from my controllers. After some research, it appears I can't localize the DisplayFormat in the same manner as the other data annotations. Other posts on SO indicate I should create a custom attribute that inherits from Attribute or DisplayAtttribute.

DisplayFormat data annotation using resource string

Model Class DisplayFormat() How can I localization NullDisplayText?

Ideally I would like to retrieve the correct format string from my shared resource file within the custom attribute while passing in the ResourceKey name. I am not sure how to go about setting this up. Possibly using the IStringLocalizer<SharedResource>?

I have an extension method to setup localization services at startup

public static class LocalizationExtensions
{
    public static IServiceCollection AddLocalizationServices(this IServiceCollection services)
    {
        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new List<CultureInfo>
            {
                new CultureInfo("en-US"),
                new CultureInfo("es-MX")
            };

            options.DefaultRequestCulture = new RequestCulture("en-US");
            // Formatting numbers, dates, etc.
            options.SupportedCultures = supportedCultures;
            // UI strings that we have localized.
            options.SupportedUICultures = supportedCultures;
        });

        services.AddLocalization(options => { options.ResourcesPath = "Resources"; } );

        services.AddControllersWithViews()
            .AddRazorRuntimeCompilation()
            .AddViewLocalization(options => { 
                options.ResourcesPath = "Resources"; 
            })
            .AddDataAnnotationsLocalization(options => {
                options.DataAnnotationLocalizerProvider = (type, factory) =>
                {
                    return factory.Create(typeof(SharedResource));
                }; 
            });

        //services.AddScoped<RequestLocalizationCookiesMiddleware>();

        return services;
    }
}

In my configure method in startup

    var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(options.Value);

Any help would be appreciated.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user351479
  • 227
  • 1
  • 2
  • 8
  • I'm afraid not.You need to create a custom attribute that inherits from Attribute or DisplayAtttribute as you said in your question. – Yiyi You Dec 02 '21 at 06:08
  • @YiyiYou I tried to find a solution using DI with attributes. It appears DI for attributes can be done in ASP.NET Core using TypeFilterAttribute and ServiceFilterAttribute, but not applicable for properties of a class. https://stackoverflow.com/questions/29915192/dependency-injection-in-attributes . I ended up inheriting from DisplayFormat Attribute and leveraging the ResourceManagerStringLocalizerFactory in my custom attribute ctor. I was able to retrieve the value from my shared resource file. I was hoping for a cleaner way, but this works for me – user351479 Dec 02 '21 at 13:20

0 Answers0