在Controller

时间:2016-08-10 13:47:02

标签: asp.net-core httpcontext

我需要在控制器外部的AspNet Core中获取HttpContext。在较旧的AspNet 4中,我可以使用HttpContext.Current来获取它,但它似乎在新的AspNet中被删除了。我发现的唯一解决方法是通过依赖注入解析IHttpContextAccessor并向它询问HttpContext,但是为了注入IHttpContextAccessor,我需要在应用程序启动中添加IHttpContextAccessor作为单例:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

我研究了它,这是我找到的唯一方法。我谷歌它和IHttpContextAccessor被删除作为依赖解析器中的默认值,因为它是非常重的依赖。还有其他方法可以达到这个目的吗?

修改 我想知道如果不是将它作为Singleton添加到依赖项解析器中,我可以在同一个地方使用HttpContextAccessor的实例将它保存在我自己的单例类中吗?

3 个答案:

答案 0 :(得分:5)

如果要将遗留应用程序移植到相当复杂的ASP.Net Core,则需要完全重新设计才能与.Net Core DI系统正常工作。如果您不想这样做,可以通过在服务定位器中再次使此功能全局化来“欺骗”。要做到这一点(如果你可以避免,不推荐这样做):

public class RequestContextManager
{
  public static RequestContextManager Instance { get; set; }

  static RequestContextManager()
  {
    Instance = new RequestContextManager(null);
  }

  private readonly IHttpContextAccessor contextAccessor;

  public RequestContextManager(IHttpContextAccessor contextAccessor)
  {
    this.contextAccessor = contextAccessor;
  }

  public HttpContext CurrentContext
  {
    get
    {
      if (contextAccessor == null)
        return null;
      return contextAccessor.HttpContext;
    }
  }
}

// In Startup.cs
public void Configure(IApplicationBuilder app,...)
{
  ...
  RequestContextManager.Instance = new RequestContextManager(app.ApplicationServices.GetService<IHttpContextAccessor>());
  ...
}

// In your code
var httpContext = RequestContextManager.Instance.CurrentContext;

答案 1 :(得分:2)

要使HttpContext有效,调用您的类的程序流必须来自控制器或某个中间件组件。您只需将对HttpContext的引用传递给您的类。

答案 2 :(得分:2)

为了直接回答为什么这个问题,GitHub Announcement说明在IHttpContextAccessor中跟踪HttpContext状态是非常重要的。所以它只是根据需要移动了。然而,HttpContext仍然可以在Controller中使用,而不会被注入。

我不相信你会在项目层面上引入新的依赖关系,只需通过依赖注入进入类,或者在需要时从IServiceProvider中获取它。