简体   繁体   中英

Localization Cookie not being created in Blazor server-side app

I set up localization in Startup.cs :

services.AddLocalization(options => options.ResourcesPath = "Resources");

and:

var supportedCultures = new[] { "en-US", "de-DE", "sv-SE" };
app.UseRequestLocalization(supportedCultures);

I also added the following in the body section of the _Host.cshtml file:

@{
    this.HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
        new RequestCulture(
            CultureInfo.CurrentCulture,
            CultureInfo.CurrentUICulture)),
            new CookieOptions {
                Expires = DateTimeOffset.UtcNow.AddYears(1),
                SameSite = SameSiteMode.None
            }
    );
 }

I created a culture controller:

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture, culture)),
                        new CookieOptions {
                            Expires = DateTimeOffset.UtcNow.AddYears(1),
                            SameSite = SameSiteMode.None
                        }
            );
        }

        return LocalRedirect(redirectUri);
    }
}

And a razor component which has a method to set the culture by doing:

private void Navigate(CultureInfo info)
{
    var uri = new Uri(navigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
    var cultureEscaped = Uri.EscapeDataString(info.Name);
    var uriEscaped = Uri.EscapeDataString(uri);

    navigationManager.NavigateTo(
        $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
        forceLoad: true);
}

Whilst debugging, the controller action is called with the correct parameters as expected. However, the localization cookie is not being created (checked the Application tab in the Developer tools in Chrome).

The cookie options are:

services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

I am also using a custom ticket store for authentication cookies and it is setup as follows:

services.AddSingleton<ITicketStore, CookieMemoryTicketStore>();
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
        .Configure<ITicketStore>((options, store) => {
            options.ExpireTimeSpan = TimeSpan.FromDays(14);
            options.SlidingExpiration = true;
            options.SessionStore = store;
        });

EDIT

A blank Blazor server-side app with localization can be found in this Github repo . Changing locale still doesn't work.

UPDATE

The problem lies with the CookiePolicyOptions above. Culture cookie creation works if the cookie options are changed as follows:

services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => false;
    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
});

Which obviously I don't want to do. I need to implement the cookie consent.

How can I implement the cookie policy options and use the culture cookie too?

Try this code:

Add function for RequestLocalizationOptions in startup:

   private RequestLocalizationOptions GetLocalizationOptions()
        {
            var supportedCultures = new[] { "en-US", "de-DE", "sv-SE" };

            var localizationOptions = new RequestLocalizationOptions()
                .SetDefaultCulture("de-DE")
                .AddSupportedCultures(supportedCultures )
                .AddSupportedUICultures(supportedCultures );

            return localizationOptions;
        }

Add this function to you `config`:
 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseRequestLocalization(GetLocalizationOptions());

Continue with your code...

It could be that the context your app is being run in is blocking the cookie. For example, I have noticed that my Blazor app being run within the Teams client blocks the setting of the.AspNetCore.Culture cookie. When I go to the Blazor app through the browser directly, I can see it being set.

If this is the case for you, what you could do is manually set the CurrentCulture and CurrentUICulture properties on the static CultureInfo class wherever localization is relevant.

This worked for me:

builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
});

Controller:

if (culture != null)
{
    HttpContext.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(culture, culture)), new CookieOptions { Expires = DateTime.UtcNow.AddYears(1), SameSite = SameSiteMode.Lax });
}

return LocalRedirect(redirectUri);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM