cerahe3782
cerahe3782

Reputation: 49

Razor .resx view localization

How to easily localize the view (only .cshtml and the javascript in this file). Please help me, I've spent about 5 hours with 0 result already, the official documentation is overcomplicated https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.1 Everything easier is outdated.

I am stuck with creating a name for the resx file

The View is called IndexPage.cshtml, the resource file is called SharedResource.en-US.resx

Using this

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
<p>@Localizer["Hello"]</p>

prints me just Hello, but not the translation of this.

Upvotes: 1

Views: 2035

Answers (1)

Hameed
Hameed

Reputation: 1615

The reason why it prints Hello is because it cannot find the matched localization resource file for the class or view you want to localize, when it cannot find the resource name/key it would print the text (key) as is.

There are two approaches to do localization:

A) If you decide to go with the way mentioned in the official documentation (using Localizer/IStringLocalizer) you need to do the following:

  1. create a Resources folder and put in it the .resx files with the proper naming convention which is:

You need to name your .resx files to mimic the path of their associated view/class file that you want to localize.

E.g.: if you have a HomeController with Index action, and you have a view for that Index located under Views/Home/Index.cshtml you then need to name your resx file as: views.home.index.en-US.resx

or you can create same folder structure as the views/controller inside your resources folder, e.g.: Resources/Views/Home/Index.en.resx.

  1. In your startup.cs you need to register the required services to support localization and configure them by doing:
//in your ConfigureServices method

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

services.AddMvc()
     .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
     .AddDataAnnotationsLocalization();

and:

//in your Configure method

var supportedCultures = new[]
{
//add the cultures you support..
     new CultureInfo("en-US"),
     new CultureInfo("fr"),
};

app.UseRequestLocalization(new RequestLocalizationOptions
{
     // Set the default culture.
     DefaultRequestCulture = new RequestCulture("en-US"), 
     // Formatting numbers, dates, etc.
     SupportedCultures = supportedCultures,
     // UI strings that we have localized.
     SupportedUICultures = supportedCultures
});
  1. When a request comes in it goes through a specific middleware to decide which culture to use using one of these providers:

    • QueryStringRequestCultureProvider.
    • CookieRequestCultureProvider. Most apps uses this mechanism to persist the user culture.
    • AcceptLanguageHeaderRequestCultureProvider.
  2. Run your app and test it using QueryStringRequestCultureProvider, e.g.: https://localhost:5001/?culture=fr

Note: You need to have a culture fallback behavior which will handle any unsupported cultures by having a .resx file without .Language_Code prefix, e.g.: views.home.index.resx which basically contains the main language of your app.


B) If you feel like approach A is too much:

If you want to have specific number of .resx files only e.g.: SharedResource.resx, SharedResource.fr.resx, Messages.resx, Messages.fr.resx, and Errors.resx , Errors.fr.resx, then you can create those .resx files inside your Resources folder.

Then in your startup.cs:

//in your ConfigureServices method
services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
services.AddMvc();

and:

//in your Configure method

var supportedCultures = new[]
{
//add the cultures you support..
     new CultureInfo("en-US"),
     new CultureInfo("fr"),
};

app.UseRequestLocalization(new RequestLocalizationOptions
{
     // Set the default culture.
     DefaultRequestCulture = new RequestCulture("en-US"), 
     // Formatting numbers, dates, etc.
     SupportedCultures = supportedCultures,
     // UI strings that we have localized.
     SupportedUICultures = supportedCultures
});

Finally, you can access the resource files using the resource file name, e.g.: @SharedResource.Hello

Note: you need to reference Resources in your _ViewImports.cshtml to be able to use them in your views.


I know this is a long answer, but i wanted to provide you with 2 different approaches so you can decide which is best for your use-case.

Upvotes: 4

Related Questions