0

I am setting and getting cookies in a ASP.NET Core WebApp. The Microsoft Docs says "After you add a cookie by using the HttpResponse.Cookies collection, the cookie is immediately available in the HttpRequest.Cookies collection, even if the response has not been sent to the client". However, I find that a cookie can't be read immediately after setting; see Set() below which always returns false. That said, the browser's storage inspector shows that it was actually set.

SO 3230133 raised the same issue in the context of PHP and the answer suggested that the cookie isn't set until the response is sent back to the client, and isn't available in your PHP until the next request from the client after that. Is this the same true in the context of ASP.NET Core? Is there a workaround similar to PHP $_COOKIE['uname'] for setting the cookie value somewhere so it can be read before the next request from the client?

The Microsoft Docs relate to .NetFramework 4.8, but there isn't an alternative for .Net Core. Is this something that works for the former, but not the latter?

public class MyCookies
{
   public IHttpContextAccessor Accessor { get; private set; }

   public MyCookies(IHttpContextAccessor accessor)
   {
      Accessor = accessor;
   }

   public bool Set(string name, string value)
   {
      var rc = false;
      Accessor.HttpContext.Response.Cookies.Append(name, value); 
      if (Accessor.HttpContext.Request.Cookies.TryGetValue(name, out var result) && (result == value))
         rc = true;
      return rc;
   }
}

public class SettingsModel : PageModel
{
   private readonly IHttpContextAccessor _httpContextAccessor;

   public SettingsModel(IHttpContextAccessor httpContextAccessor)
   {
      _httpContextAccessor = httpContextAccessor;
   }

   public IActionResult OnPost()
   {
      var cookies = new MxCookies(_httpContextAccessor);
      if (cookies.SetValue(".AspNetCore.Culture", "fr-CH") == false)
      {
         var stop = true; 
      }
      return new RedirectToPageResult("Index");
   }
}

Don't forget to invoke services.AddHttpContextAccessor() in Startup.ConfigureServices()

wpqs
  • 657
  • 1
  • 7
  • 18

2 Answers2

0

This could be related to GDPR and .NET Core app not setting essential cookies without explicit consent.

Have a look at https://learn.microsoft.com/en-us/aspnet/core/security/gdpr?view=aspnetcore-2.1

Essentially, you need to pass in the following options when setting the cookie:

var options = new CookieOptions
{
    Expires = DateTime.Now.AddMinutes(60),
    IsEssential = true
};

Accessor.HttpContext.Response.Cookies.Append(name, value, options);
Ben D
  • 669
  • 1
  • 11
  • 19
  • It's was a good suggestion, but unfortunately, the changes you proposed didn't fix the problem on my machine. I would be interested to know whether anyone can duplicate the issue in an ASP.NET Core 3.1 WebApp by calling MyCookies.Set() from an OnPost() method as shown above. – wpqs Jul 27 '20 at 19:30
0

Unfortunately in .NET Core the cookie is NOT immediately available in the HttpRequest.Cookies collection. In this respect the behavior is different than for Framework as confirmed in ASP.NET Core issue 24442.

I had hoped to use a Cookie to store the culture setting as determined in middleware because I suspect storing it Thread.CurrentThread.CurrentUICulture will not work in async methods as there is no guarantee that the thread will be the same as one used for the setting made by my middleware. Can anyone suggest a work-around?

wpqs
  • 657
  • 1
  • 7
  • 18