How to use IHttpContextAccessor in static class to set cookies
Solution 1
While i would advise staying away from static class scenarios like this, it is still possible to achieve what you are asking for.
Assuming a static class like...
public class MyStaticHelperClass {
private static IHttpContextAccessor httpContextAccessor;
public static void SetHttpContextAccessor(IHttpContextAccessor accessor) {
httpContextAccessor = accessor;
}
public static void addReplaceCookie(string cookieName, string cookieValue) {
var HttpContext = httpContextAccessor.HttpContext;
if (HttpContext.Request.Cookies(cookieName) == null) {
// add cookie
HttpCookie s = new HttpCookie(cookieName);
s.Value = cookieValue;
s.Expires = DateTime.Now.AddDays(7);
HttpContext.Response.Cookies.Add(s);
} else {
// ensure cookie value is correct
HttpCookie existingSchoolCookie = HttpContext.Request.Cookies(cookieName);
existingSchoolCookie.Expires = DateTime.Now.AddDays(7);
existingSchoolCookie.Value = cookieValue;
HttpContext.Response.Cookies.Set(existingSchoolCookie);
}
}
}
You would add the accessor in Startup.ConfigureServices
since it is no longer added automatically
public void ConfigureServices(IServiceCollection service) {
//Register IHttpContextAccessor and its implementation.
services.AddHttpContextAccessor();
services.AddTransient<IMyService, MyService>();
services.AddMvc();
//...
}
And get the service via injection into the Startup.Configure
method
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor accessor)
{
MyStaticHelperClass.SetHttpContextAccessor(accessor);
//...
}
Now with that done. I would still strongly advise converting your static class into a service whose concrete implementation would use the IHttpContextAccessor
as a dependency that can be injected via its constructor.
public interface ICookieService {
void AddReplaceCookie(string cookieName, string cookieValue);
}
public class CookieService : ICookieService {
IHttpContextAccessor httpContextAccessor;
public CookieService(IHttpContextAccessor httpContextAccessor) {
this.httpContextAccessor = httpContextAccessor;
}
public void AddReplaceCookie(string cookieName, string cookieValue) {
var HttpContext = httpContextAccessor.HttpContext;
if (HttpContext.Request.Cookies(cookieName) == null) {
// add cookie
HttpCookie s = new HttpCookie(cookieName);
s.Value = cookieValue;
s.Expires = DateTime.Now.AddDays(7);
HttpContext.Response.Cookies.Add(s);
} else {
// ensure cookie value is correct
HttpCookie existingSchoolCookie = HttpContext.Request.Cookies(cookieName);
existingSchoolCookie.Expires = DateTime.Now.AddDays(7);
existingSchoolCookie.Value = cookieValue;
HttpContext.Response.Cookies.Set(existingSchoolCookie);
}
}
}
...that could then be registered with the Services collection...
public void ConfigureServices(IServiceCollection service) {
services.AddHttpContextAccessor();
services.AddTransient<ICookieService, CookieService>();
services.AddMvc();
}
...and be available for injection into classes that have need of it's use.
public class SomeClassThatNeedCookieServicesController : Controller {
ICookieService cookieService;
public SomeClassThatNeedCookieServicesController(ICookieService cookieService) {
this.cookieService = cookieService;
}
//...
}
This is how I do it to manage session cookies in my applications.
Solution 2
If possible, don't use static class
. But if you have to use, sending IHttpContextAccessor
as a parameter might be a solution.
public static void addReplaceCookie(string cookieName, string cookieValue, IHttpContextAccessor accessor)
{
//your code
}
public class CallerClass
{
private readonly IHttpContextAccessor _accessor;
public CallerClass(IHttpContextAccessor accessor)
{
_accessor = accessor;
addReplaceCookie(cookieName, cookieValue, accessor);
}
}
Solution 3
in Startup.ConfigureServices:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
later in Startup.Configure add by DI IServiceProvider and use it to extract IHttpContextAccessor like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider svp)
{
IHttpContextAccessor accessor = svp.GetService<IHttpContextAccessor>();
MyRepository.SetHttpContextAccessor(accessor);
user973671
Updated on June 13, 2022Comments
-
user973671 almost 2 years
I am trying to create a generic
addReplaceCookie
method in a static class. The method would look something like thispublic static void addReplaceCookie(string cookieName, string cookieValue) { if ((HttpContext.Current.Request.Cookies(cookieName) == null)) { // add cookie HttpCookie s = new HttpCookie(cookieName); s.Value = cookieValue; s.Expires = DateTime.Now.AddDays(7); HttpContext.Current.Response.Cookies.Add(s); } else { // ensure cookie value is correct HttpCookie existingSchoolCookie = HttpContext.Current.Request.Cookies(cookieName); existingSchoolCookie.Expires = DateTime.Now.AddDays(7); existingSchoolCookie.Value = cookieValue; HttpContext.Current.Response.Cookies.Set(existingSchoolCookie); } }
I know that in order to get the
HttpContext
in asp.net core you have to use theIHttpContextAccessor
. But I cannot inject it into a static class.Is there another way to get access to it?
I am using rc1-final.
-
user973671 almost 8 yearsAwesome, I think Im starting to get it. Do you know, is there a way to replace a cookie in asp.net core, or does append automatically replace it?
-
Nkosi almost 8 yearsWhat do you mean by append? I'm not sure I understand. I normally use the
Response.Cookies.Set(cookie)
if that is what you mean. where the cookie has the key and value(s). -
user973671 almost 8 yearsYea, for some reason Response.Cookies.Set is throwing an error for me. I have to use Response.Cookies.Append(cookieName, cookieValue, CookieOption); But thats fine. Thanks for your help!
-
amir about 4 yearswould you please describe why you don`t recommend static class for this scenarios and what is the scenarios you recommend for it?