Reputation: 1339
I implemented the localization in my app following this documentation and actually I got a problem when I change the language through the select box, infact when I select english the application still have the italian language.
When I change the language seems that the app execute a refresh but the language is always setted to italian, the weird thing is that if I add a query string in the url which have this http://localhost:5000/?culture=en
then the application will run in english and the selected item in the select will be setted to english too.
Inside the ConfigureService
method I added the following:
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("it-IT"),
new CultureInfo("en")
};
options.DefaultRequestCulture = new RequestCulture("it-IT");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
});
so as you can see I have only two languages: english, italian
both of them have the .resx
files available inside the folder Resources
, specifically, I added the file for each Controller
in the properly folder:
then in the Configure
method I added this: app.UseRequestLocalization();
before UseMvc
as indicated in the documentation.
Then I created a View
inside Shared
folder called _SelectLanguagePartial.cshtml
, this View
contains the following content:
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
var cultureItems = LocOptions.Value.SupportedUICultures
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
<form id="selectLanguage" asp-controller="Language"
asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
method="post" class="form-horizontal" role="form">
<label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label>
<select name="culture" onchange="this.form.submit();"
asp-for="@requestCulture.RequestCulture.UICulture.Name"
asp-items="cultureItems"></select>
</form>
</div>
I load this View
in the _Layout.cshtml
footer which contains the basic html
of the site: @await Html.PartialAsync("_SelectLanguagePartial")
.
Now I also created another controller called LanguageController
which contains the method SetLanguage
and it's called each time I select an item from the select
available in the footer
public class LanguageController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) });
return LocalRedirect(returnUrl);
}
}
when I select english the variable culture
contains en
but the site always display the italian language.
What I missed?
UPDATE
This is actually the content of the variables for the SelectLanguage
method:
as you can see the culture is passed correctly, after the execution of this method there is a refresh but instead of get the english language I get italian.
UPDATE 2
This is the operation flow that I did:
Upvotes: 1
Views: 2256
Reputation: 1339
Never though a similar thing, as I said I' not an ASP.NET Core
expert, and I'm currently learning it, but the problem is not caused by the code posted in my question but is caused by this:
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
The "bug" is on the line: options.CheckConsentNeeded = context => true;
I don't know why this prevent to Append
a Cookie
which is in this case related to the language, maybe this is a bug? Anyway, I commented this line of code, but if someone could provide an explaination for this I'll be glad.
Upvotes: 1
Reputation: 29966
For your current settings, you will need to do like below:
public class HomeController : Controller
{
private readonly IStringLocalizer<HomeController> _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
ViewData["Title"] = _localizer["Title"];//"Your application description page.";
return View();
}
And then, use ViewData["Title"]
in the view to access the licalizered content.
If you want to access localizer like below in the view:
@inject IViewLocalizer Localizer
<label>@Localizer["Title"]</label>
You need to create View localizer like below:
Upvotes: 1