6

Shared RESX file for data annotation localization in ASP.NET Core 2.0

 2 years ago
source link: https://joonasw.net/view/aspnet-core-data-annotation-localization-shared-resx-file
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Shared RESX file for data annotation localization in ASP.NET Core 2.0

Posted on: 20-03-2018 6 Comments



This is a continuation to my ASP.NET Core Localization Deep Dive.

Something which was asked here today by Dwayne Hawkins was:

Why can't it just use the SharedResources file, which I made for my views. I don't want 5000 seperate resx files for all my viewmodels ...

A very valid concern. If we have a lot of view models, we would not want to copy paste error message translations like "{0} is required" to hundreds of RESX files. Updates would be a nightmare. So I found a solution for the problem. I am not sure if it is the best solution, but it does work.

Configuring the Data Annotation Localizer Provider

First I noticed there is an overload on AddDataAnnotationsLocalization which takes an Action which can be used to configure options. The options class is pretty simple:

/// <summary>
/// Provides programmatic configuration for DataAnnotations localization in the MVC framework.
/// </summary>
public class MvcDataAnnotationsLocalizationOptions
{
    /// <summary>
    /// The delegate to invoke for creating <see cref="IStringLocalizer"/>.
    /// </summary>
    public Func<Type, IStringLocalizerFactory, IStringLocalizer> DataAnnotationLocalizerProvider;
}

It has only one property. But that is the delegate used to create the localizers! By default, it uses the type of the model to create a localizer with the localizer factory.

Here is what I did:

services.AddMvc().AddDataAnnotationsLocalization(o =>
{
    o.DataAnnotationLocalizerProvider = (type, factory) =>
    {
        return factory.Create(typeof(SharedResource));
    };
});
services.AddLocalization(o =>
{
    o.ResourcesPath = "Resources";
});

SharedResource here is an empty class. I have a corresponding SharedResource.en-US.resx and SharedResource.fi-FI.resx file in my Resources folder. This means any annotation localizations will now come from those files!

The Finnish RESX file contains values like this:

  • Name: Nimi
  • {0} is required: {0} on pakollinen

Then if we have a model, we can do annotations like this:

public class MyViewModel
{
    [Display(Name = "Name")]
    [Required(ErrorMessage = "{0} is required")]
    public string Name { get; set; }
}

And we get localized error messages :)

Shorter article this time, hope this is useful!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK