如何在静态类中使用IHttpContextAccessor来设置cookie

时间:2016-05-19 16:42:27

标签: c# cookies asp.net-core asp.net-core-mvc asp.net5

我正在尝试在静态类中创建通用addReplaceCookie方法。该方法看起来像这样

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

}

我知道为了获得asp.net核心中的HttpContext,您必须使用IHttpContextAccessor。但我无法将其注入静态类。

是否有其他方法可以访问它?

我正在使用rc1-final。

3 个答案:

答案 0 :(得分:10)

虽然我建议远离这样的静态类场景,但仍然可以实现你所要求的。

Startup.ConfigureServices方法中,您可以致电services.BuildServiceProvider()IServiceProvider来解析您寻求的类型。这有点像黑客但它有效。

假设像......这样的静态类

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

您可以在启动时配置课程

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

现在完成了。我仍然强烈建议将静态类转换为一个服务,其具体实现将使用IHttpContextAccessor作为可通过其构造函数注入的依赖项。

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

...然后可以在服务集合中注册......

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

...并且可以注入需要使用它的类。

public class SomeClassThatNeedCookieServicesController : Controller {
    ICookieService cookieService;

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

这就是我在应用程序中管理会话cookie的方法。

答案 1 :(得分:3)

如果可能,请勿使用static class。但是如果你必须使用,发送IHttpContextAccessor作为参数可能是一个解决方案。

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

答案 2 :(得分:1)

在Startup.ConfigureServices中:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

稍后在Startup中。配置DI IServiceProvider添加并使用它来提取IHttpContextAccessor,如下所示:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider svp)
    {
        IHttpContextAccessor accessor = svp.GetService<IHttpContextAccessor>();
        MyRepository.SetHttpContextAccessor(accessor);