My Razor page looks like this.
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
<h1>@Localizer["Index"]</h1>
...
My Startup.cs contains the following.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddLocalization(a => a.ResourcesPath = "/");
services.Configure<RequestLocalizationOptions>(a =>
{
CultureInfo[] supportedCultures = {
new CultureInfo("sv-SE"),
new CultureInfo("se")
};
a.DefaultRequestCulture = new RequestCulture("se");
a.SupportedCultures = supportedCultures;
a.SupportedUICultures = supportedCultures;
});
...
}
I placed a file called Controllers.HomeController.se.resx directly in the project's root. The controller HomeController contains the injection.
public class HomeController : Controller
{
private readonly Context _context;
private readonly IStringLocalizer<HomeController> _localizer;
public HomeController(Context context, IStringLocalizer<HomeController> localizer)
{
_context = context;
_localizer = localizer;
}
...
}
The application doesn't crash but the string renedered is Index and not the value from the RESX file. I've tried to follow the docs as closely as possible but apparently I've missed something. I need help finding what that would be.
I breakpointed and checked the value of _localizer["Index"] in the constructor. As expected, the flag for the file not being found is set to true. Checking the value of SearchedLocation gives me Web...Controllers.MemberController. I can't tell if those three dots is the correct one for the RESX file in the project's root. I was expecting se somewhere in the name too.
If you want to place you resources files in root of the project you should set ResourcesPath
as following
services.AddLocalization(a => a.ResourcesPath = ""); //empty string
With this settings SearchedLocation
will give you Web.Controllers.MemberController
which points to Controllers.MemberController.resx
file in the root of the project.
To use localization in view you have to follow Views.{ControllerName}.{ViewName}.resx
pattern. For example if you have HomeController
and About
view in it you need to have Views.Home.About.resx
file to use localization.
Another convention resource reader follows when searching for localization files is searching the files in respective folders rather than by dot separated names. For example if ResourcesPath
is set to "Resources"
the following variants are equal
Resources.Views.Home.About.resx
Resources\Views.Home.About.resx
Resources\Views\Home.About.resx
Resources\Views\Home\About.resx
So it's possible to structure your localization files by folders.
And you didn't specify you added app.UseRequestLocalization()
in your Startup.cs
. If you don't do this your application won't be able to determine request culture and it will always point to default resource file. Read more in the docs.
Note
There are 2 ways of configuring RequestLocalizationOptions
for request localization, via services.Configure<RequestLocalizationOptions>
or passing constructed options object (or delegate) to app.UseRequestLocalization
. Effectively there is no difference between these approaches, they are totally equal in terms of localization middleware. But if at any point of an application you need to get RequestLocalizationOptions
you won't be able to get value passed to app.UseRequestLocalization
. But it is easy to accompish with services.Configure<RequestLocalizationOptions>
(it's general approach described in the docs)
public class HomeController : Controller
{
private readonly RequestLocalizationOptions _requestLocalizationOptions;
public HomeController(IOptions<RequestLocalizationOptions> options)
{
_requestLocalizationOptions = options.Value;
}
//..
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With