Aldemar Cuartas Carvajal
Aldemar Cuartas Carvajal

Reputation: 2431

Globalization and localization in ASP.NET Core 2.0 shared satellite assembly and in main project

Recently I started a ASP.NET Core 2.0 solution. I needed to separate ViewModels classes in a project to share with other projects. Every view model class has its DataAnnotations properties and I need to use globalization and localization. Every project that uses ViewModels project as reference also has its own Language resource in Resources/Controllers and Resources/Views folders.

Example of LoginViewModel.cs in Backend project:

public class LoginViewModel
{
    [Required]
    [Display(Name ="UserName")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password"))]
    public string Password { get; set; }
}

According to MSDN documentation, I could create a SharedResource class and a SharedResource.es.resx (not a default resource file like SharedResource.resx) and by setting custom class DataAnnotation localizer Provider in main ASP.NET project by using following code in ConfigureServices:

services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
            .AddDataAnnotationsLocalization(options =>
             {
                options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(Backend.Resources.SharedResources));
             });

in Configure Method:

var supportedCultures = new[]
        {
            new CultureInfo("es-CO")
        };

        app.UseRequestLocalization(new RequestLocalizationOptions()
        {
            DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en-US"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        });

I tried before mentioned scenario however when I run app, Login cshtml that uses LoginViewModel shows UserName and Password as it and not "Usuario" and "Contraseña" as they are in SharedResource.es.resx. ¿Is not possible to use or inject IStringLocalizer in an assembly so I must use the default Resource Files?

I hope being clear!

Upvotes: 0

Views: 1725

Answers (1)

NightOwl888
NightOwl888

Reputation: 56909

Looking at the MSDN page you linked:

Resource file naming

Resources are named for the full type name of their class minus the assembly name. For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx. A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named Controllers.HomeController.fr.resx. If your targeted class's namespace is not the same as the assembly name you will need the full type name. For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx.

Since your model class is named Backend.LoginViewModel and presumably the assembly name is Backend, the resource file should be named LoginViewModel.resx for the default culture and LoginViewModel.<culture>.resx for each localized culture.

In the sample project, the ConfigureServices method sets the ResourcesPath to "Resources", so the project relative path for the home controller's French resource file is Resources/Controllers.HomeController.fr.resx. Alternatively, you can use folders to organize resource files. For the home controller, the path would be Resources/Controllers/HomeController.fr.resx. If you don't use the ResourcesPath option, the .resx file would go in the project base directory. The resource file for HomeController would be named Controllers.HomeController.fr.resx. The choice of using the dot or path naming convention depends on how you want to organize your resource files.

This path clearly must be within the main AspNetCore assembly or it won't be able to find these folders.

Upvotes: 0

Related Questions