user973671
user973671

Reputation: 1650

How to use IHttpContextAccessor in static class to set cookies

I am trying to create a generic addReplaceCookie method in a static class. The method would look something like this

public 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 the IHttpContextAccessor. But I cannot inject it into a static class.

Is there another way to get access to it?

I am using rc1-final.

Upvotes: 13

Views: 25489

Answers (4)

d_f
d_f

Reputation: 4859

For those who still need IHttpContextAccessor in static context, the simplest solution is to use constructor:

private static readonly IHttpContextAccessor http = new HttpContextAccessor();

The accessor is already static inside, all the instances internally share the same AsyncLocal<HttpContextHolder>.

Upvotes: 0

Nkosi
Nkosi

Reputation: 247423

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.

Upvotes: 25

EladTal
EladTal

Reputation: 2846

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

Upvotes: 3

adem caglin
adem caglin

Reputation: 24123

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

Upvotes: 4

Related Questions