Search code examples
c#asp.net-core-mvcasp.net-core-6.0asp.net-core-localization

Localizer ASP.NET Core 6 will not be saved


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

Solution

  • 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