Charanoglu
Charanoglu

Reputation: 1339

Cannot change the localization

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:

enter image description here

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:

enter image description here

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:

enter image description here

enter image description here

enter image description here

Upvotes: 1

Views: 2256

Answers (2)

Charanoglu
Charanoglu

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

Edward
Edward

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:

enter image description here

Upvotes: 1

Related Questions