Cómo usar IHttpContextAccessor en clase estática para configurar cookies

Cómo usar IHttpContextAccessor en clase estática para configurar cookies

Si bien recomendaría mantenerse alejado de escenarios de clase estática como este, aún es posible lograr lo que está pidiendo.

En el Startup.ConfigureServices método al que puede llamar services.BuildServiceProvider() para obtener el IServiceProvider para resolver el tipo que buscas. Es un truco pero funciona.

Asumiendo una clase estática como...

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

Configurarías tu clase durante el inicio

public IServiceProvider ConfigureServices(IServiceCollection service) {
    services.AddTransient<IMyService, MyService>();
    services.AddMvc();

    //this would have been done by the framework any way after this method call;
    //in this case you call the BuildServiceProvider manually to be able to use it
    var serviceProvider = services.BuildServiceProvider();

    //here is where you set you accessor
    var accessor = serviceProvider.GetService<IHttpContextAccessor>()
    MyStaticHelperClass.SetHttpContextAccessor(accessor);

    return serviceProvider;
}

Ahora con eso hecho. Todavía recomendaría encarecidamente convertir su clase estática en un servicio cuya implementación concreta usaría el IHttpContextAccessor como una dependencia que se puede inyectar a través de su 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);
        }
    }
}

...que luego podría registrarse con la colección de Servicios...

public void ConfigureServices(IServiceCollection service) {
    services.AddTransient<ICookieService, CookieService>();
    services.AddMvc();
}

...y estar disponible para inyección en las clases que necesitan su uso.

public class SomeClassThatNeedCookieServicesController : Controller {
    ICookieService cookieService;

    public SomeClassThatNeedCookieServicesController(ICookieService cookieService) {
        this.cookieService = cookieService;
    }
}

Así es como lo hago para administrar las cookies de sesión en mis aplicaciones.


Si es posible, no use static class . Pero si tienes que usar, envía IHttpContextAccessor como parámetro podría ser una solución.

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