I created a sample web application with ASP.NET Core to test the storage and retrieval of the cookie. Unfortunately, I'm not able to store cookies.
I've read these questions for my problem:
Cookies in ASP.NET Core rc2
Create cookie with ASP.NET Core
Cookies and ASP.NET Core
But unfortunately I did not find a good answer.
I will first request an IndexA action to store the cookie. The code runs without any errors,but when I request IndexB action. Does not find the specified value
This is IndexA Action:
public IActionResult IndexA()
{
Response.Cookies.Append("mykey", "myvalue",
new CookieOptions()
{
Expires = DateTime.Now.AddMinutes(10)
});
return View();
}
This is IndexB Action:
public IActionResult IndexB()
{
var cookie = Request.Cookies["mykey"];
return View();
}
And This is Startup Class:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
I think it might have to do with the GDPR-related feature that ASP.NET Core 2.1 ships with. My understanding is that it allows websites to define which cookies are essential or not for the browser, and the non-essential ones won't be sent.
The first thing I can think of is to simply remove the check for consent for non-essential cookies. Do not do this in production as you might violate regulation!. Change:
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
to
services.Configure<CookiePolicyOptions>(options =>
{
// No consent check needed here
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
The second potential way of fixing this is declaring your cookie as essential, so no matter what the consent check result is, your cookie will be sent over to the browser. To do this, change:
Response.Cookies.Append(
"mykey",
"myvalue",
new CookieOptions()
{
Expires = DateTime.Now.AddMinutes(10)
});
with
Response.Cookies.Append(
"mykey",
"myvalue",
new CookieOptions()
{
Expires = DateTime.Now.AddMinutes(10),
// Marking the cookie as essential
IsEssential = true
});
I am Working with ASP.NET core 2.2. Here is what I have in my ConfigureServices(IServiceCollection services) to inject the HttpContextAccessor into my controller.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//... some code
//services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddHttpContextAccessor();
}
Here is what I have in my controller:
private readonly IHttpContextAccessor _httpContextAccessor;
public MySomethingController(IHttpContextAccessor httpContextAccessor)
{
//... some code
this._httpContextAccessor = httpContextAccessor;
}
Here is the code for the Action method:
[HttpGet]
public IActionResult SomethingToDo()
{
//... some code for my controller
//Section for handling cookies
//set the key value in Cookie
SetCookie("MyOwnKey", "Hello World from cookie", 15.0);
//read cookie from IHttpContextAccessor
string cookieValueFromContext = _httpContextAccessor.HttpContext.Request.Cookies["MyOwnKey"];
//or
string cookieValueFromRequest = GetCookie("MyOwnKey");
//Delete the cookie object
//RemoveCookie("MyOwnKey");
ViewData["CookieFromContext"] = cookieValueFromContext;
ViewData["CookieFromRequest"] = cookieValueFromRequest;
return View();
}
Then I have the following methods:
public string GetCookie(string key)
{
return Request.Cookies[key];
}
public void SetCookie(string key, string value, double? expireTime)
{
CookieOptions option = new CookieOptions();
if (expireTime.HasValue)
option.Expires = DateTime.Now.AddMinutes(expireTime.Value);
else
option.Expires = DateTime.Now.AddMilliseconds(1);
Response.Cookies.Append(key, value, option);
}
public void RemoveCookie(string key)
{
Response.Cookies.Delete(key);
}
I am able to see the cookie value in another controller and pass it to the view. I have this in the home controller:
...
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IHostingEnvironment _hostingEnvironment;
public HomeController(IHostingEnvironment hostingEnvironment, IHttpContextAccessor httpContextAccessor)
{
this._hostingEnvironment = hostingEnvironment;
this._httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
//read cookie from IHttpContextAccessor
string cookieValueFromContext = _httpContextAccessor.HttpContext.Request.Cookies["MyOwnKey"];
ViewData["CookieFromContext"] = cookieValueFromContext;
return View();
}
Good Luck
A controller exposes HttpContext.Response.Cookies... There is no need to use dependency injection through the ConfigureServices method and there is no need to add the additional property to the controller. Just call HttpContext.Response.Cookies.Append(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With