Localizer ASP.NET Core 6 will not be saved

290 Views Asked by At

I have a problem with my Localizer. If I want to change the language of the website from English to Dutch, the POST request does get sent (checked with debugging). Only the language always remains set to English and is not changed to Dutch.

I got the code from Microsoft's own documentation, and I don't understand why it doesn't work. (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/make-content-localizable?view=aspnetcore-6.0)

I am using ASP.NET Core 6.

This is my program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

builder.Services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlite(builder.Configuration.GetConnectionString("Application") ??
                          throw new InvalidOperationException("Connection string not found")));

var connectionString = builder.Configuration.GetConnectionString("Users");
builder.Services.AddDbContext<UserDbContext>(options =>
        options.UseSqlite(connectionString ?? throw new InvalidOperationException("Connection string not found")));

builder.Services.AddStackExchangeRedisCache(config =>
        config.Configuration = builder.Configuration.GetConnectionString("Redis"));
builder.Services.AddSession();
}

builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<UserDbContext>();

builder.Services.Configure<IdentityOptions>(options =>
{
    options.Lockout.AllowedForNewUsers = false;
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
    options.Lockout.MaxFailedAccessAttempts = 10;

    options.Password.RequireDigit = false;
    options.Password.RequireLowercase = false;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireUppercase = false;
    options.Password.RequiredLength = 1;
    options.Password.RequiredUniqueChars = 1;
});

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.Configure<RequestLocalizationOptions>(options => {
    var supportedCultures = new[] { "en-US", "nl" };
    options.SetDefaultCulture(supportedCultures[1])
        .AddSupportedCultures(supportedCultures)
        .AddSupportedUICultures(supportedCultures);
});

builder.Services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();

builder.Services.AddTransient<IEmailSender, EmailSender>();
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration.GetSection("AuthMessageSenderOptions"));


var app = builder.Build();

app.UseRequestLocalization(options =>
{
    var questStringCultureProvider = options.RequestCultureProviders[0];    
    options.RequestCultureProviders.RemoveAt(0);
    options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) {
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "name",
        pattern: "{name}/{controller=Home}/{action=Index}/{id?}");
    
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "",
        defaults: new { controller="Home", action="Choose" });
});

app.MapRazorPages();
app.UseSession();

app.Run();

My shared layout file (_layout.cshtml):

@{
    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="Home"
                                  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>

And the HomeController.cs:

[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);
}
2

There are 2 best solutions below

0
Ruikai Feng On BEST ANSWER

Try as below(don't configure RequestLocalizationOptions part when you regist services,part in middleware):

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[] { "en-us", "nl" };
    options.SetDefaultCulture(supportedCultures[1])
        .AddSupportedCultures(supportedCultures)
        .AddSupportedUICultures(supportedCultures);
    var questStringCultureProvider = options.RequestCultureProviders[0];
    options.RequestCultureProviders.RemoveAt(0);
    options.RequestCultureProviders.Insert(1, questStringCultureProvider);
    //Add services to the container.
});


var app = builder.Build();


app.UseRequestLocalization();

It now works well on myside:

enter image description here

0
Tariq Almalki On

change every @Localizer["......."] to @Localizer["......."].Value