【问题标题】:How to use IHttpContextAccessor in static class to set cookies如何在静态类中使用 IHttpContextAccessor 设置 cookie
【发布时间】:2016-09-16 16:41:53
【问题描述】:

我正在尝试在静态类中创建通用 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。

【问题讨论】:

  • 由于它是一个静态类,因此您可以创建一个初始化方法,该方法采用接口并在设置服务集合期间将其传入。

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


【解决方案1】:

如果可能,不要使用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】:

    虽然我建议远离这样的静态课程场景,但仍有可能实现您的要求。

    假设一个静态类...

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

    您将在Startup.ConfigureServices 中添加访问器,因为它不再自动添加

    public void ConfigureServices(IServiceCollection service) {
    
        //Register IHttpContextAccessor and its implementation.
        services.AddHttpContextAccessor();
    
        services.AddTransient<IMyService, MyService>();
        services.AddMvc();
    
        //...
    }
    

    并通过注入Startup.Configure方法获取服务

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor accessor)
    {
        MyStaticHelperClass.SetHttpContextAccessor(accessor);
    
        //...
    
    }
    

    现在完成了。我仍然强烈建议将您的静态类转换为服务,其具体实现将使用 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);
            }
        }
    }
    

    ...然后可以在 Services 集合中注册...

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

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

    public class SomeClassThatNeedCookieServicesController : Controller {
        ICookieService cookieService;
    
        public SomeClassThatNeedCookieServicesController(ICookieService cookieService) {
            this.cookieService = cookieService;
        }
    
        //...
    }
    

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

    【讨论】:

    • 太棒了,我想我开始明白了。你知道吗,有没有办法在asp.net core中替换一个cookie,或者append会自动替换它吗?
    • 追加是什么意思?我不确定我是否理解。如果这就是你的意思,我通常使用Response.Cookies.Set(cookie)。其中 cookie 具有键和值。
    • 是的,由于某种原因 Response.Cookies.Set 为我抛出了一个错误。我必须使用 Response.Cookies.Append(cookieName, cookieValue, CookieOption);不过没关系。感谢您的帮助!
    • 能否请您描述一下为什么您不推荐该场景使用静态类以及您推荐的场景是什么?
    【解决方案3】:

    在 Startup.ConfigureServices 中:

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 1970-01-01
      • 2014-04-04
      • 1970-01-01
      • 2020-10-15
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多