How to Response.Cookies.Append() in ASP.Net Core 1.1?
Asked Answered
P

3

3

I am trying to add Globalization to an Intranet application, using a cookie to allow users a culture preference. The middleware is set up and running but I have run into an issue with appending to the cookie based on the UI selection.

The method is straight from the Asp.Net Core documentation as below:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RequestLocalizationOptions>(
        options =>
        {
            var supportedCultures = new List<CultureInfo>
            {
            new CultureInfo("en-US"),
            new CultureInfo("en-GB"),
            new CultureInfo("fr-FR"),
            new CultureInfo("es-ES")
            };

            options.DefaultRequestCulture = new RequestCulture(culture: "en-GB", uiCulture: "en-GB");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });

    services.AddLocalization();
    services.AddMvc(config =>
    {
        var policy = new AuthorizationPolicyBuilder()
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(policy));
    })
    .AddViewLocalization();

    services.AddSession(options => {
        options.CookieName = "Intranet";
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(locOptions.Value);

    app.UseSession();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

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

The issues are:

  1. Response does not exist
  2. LocalRedirect does not exist

I have tried:

  1. HttpResponse, HttpRequest
  2. LocalRedirectResult
Pip answered 1/2, 2017 at 11:10 Comment(2)
Do you have that code inside a controller or is it standalone somewhere else?Darrondarrow
Possible duplicate of Cookies and ASP.NET CoreHallway
D
5

From the docs where you got that sample, you can see that the code comes from GitHub with lots of sample projects. This particular sample comes from Localization.StarterWeb.

Your two "missing" methods are actually part of ControllerBase (which is what Controller inherits from. So if you put this action method into a controller, it will work.

public class HomeController : Controller
{
    [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);
    }
}
Darrondarrow answered 1/2, 2017 at 12:58 Comment(1)
Controller ... not class. That was a silly mistake, thank you so much!Pip
P
5

In ASP .NET Core 2.1+, if you use the cookie policy feature for implementing GDPR by invoking app.UseCookiePolicy() in Startup.cs, make sure to mark your cookie as essential, otherwise it won't be sent to users who haven't accepted your policy.

Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
            new CookieOptions 
            { 
                Expires = DateTimeOffset.UtcNow.AddYears(1), 
                IsEssential = true 
            }
        );

Obviously, you should also mention the cookie in your privacy statement.

Pronto answered 2/10, 2018 at 8:12 Comment(1)
Great timing. Just starting work on a new app in 2.1, perhaps 2.2 soon and will be coming across this shortly I would imagine.Pip
M
0

First of all you've to use CookieRequestCultureProvider. Later one the action you have in the example should works just fine. I would also add this:

CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;

Here is my config:

public void ConfigureServices(IServiceCollection services)
{
    services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });

    services.AddMvc()
        .AddViewLocalization(
            Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.SubFolder,
            opts => { opts.ResourcesPath = "Resources"; }
        )
        .AddDataAnnotationsLocalization();

    services.Configure<RequestLocalizationOptions>(opts =>
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"), 
            ...               
        };
        opts.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("en-US");
        opts.SupportedCultures = supportedCultures;
        opts.SupportedUICultures = supportedCultures;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseRequestLocalization();

    app.UseMvc(routes =>
    {
        routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}");
    });
}
Milkwort answered 1/2, 2017 at 12:0 Comment(4)
This doesn't answer the question at all.Darrondarrow
And how does the code you've provided allow the user to switch culture preferences?Darrondarrow
The code which I provided is showing the configuration which I'm using to use exactly the same action as was in the question. I've also mention in the first paragraph that "...the action you have in the example should works just fine..." if the configuration will be correct.Milkwort
Thanks for posting that code. I have updated my question to include my startup elements. I am not localizing in anyway so have no .resx files to include but I think we are very similar. It is interesting that you are using Microsoft.AspNetCore.Localization.RequestCulture() for default though.Pip

© 2022 - 2024 — McMap. All rights reserved.