在ASP.NET Core中访问当前的HttpContext

我需要访问静态方法或实用程序服务中的当前HttpContext

使用传统的ASP.NET MVC和System.Web ,我只是使用HttpContext.Current静态地访问上下文。 但是,如何在ASP.NET Core中执行此操作?

HttpContext.Current在ASP.NET Core中不再存在,但是有一个新的IHttpContextAccessor ,您可以在您的依赖项中注入并用于检索当前的HttpContext

 public class MyComponent : IMyComponent { private readonly IHttpContextAccessor _contextAccessor; public MyComponent(IHttpContextAccessor contextAccessor) { _contextAccessor = contextAccessor; } public string GetDataFromSession() { return _contextAccessor.HttpContext.Session.GetString(*KEY*); } } 

Necromancing。
是的你可以
秘密提示那些迁徙的人 帆船 大块(叹气,弗洛伊德滑)的代码。
下面的方法是积极从事开发撒旦(在.NET核心框架开发人员眼中)的快速工作的黑客的邪恶carb but但它的工作原理是

public class Startup

添加一个属性

 public IConfigurationRoot Configuration { get; } 

然后在ConfigureServices中添加一个单例IHttpContextAccessor到DI。

  // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>(); 

然后在configuration中

  public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ) { 

添加DI参数IServiceProvider svp ,所以方法如下所示:

  public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ,IServiceProvider svp) { 

接下来,为System.Web创build一个replace类:

 namespace System.Web { namespace Hosting { public static class HostingEnvironment { public static bool m_IsHosted; static HostingEnvironment() { m_IsHosted = false; } public static bool IsHosted { get { return m_IsHosted; } } } } public static class HttpContext { public static IServiceProvider ServiceProvider; static HttpContext() { } public static Microsoft.AspNetCore.Http.HttpContext Current { get { // var factory2 = ServiceProvider.GetService<Microsoft.AspNetCore.Http.IHttpContextAccessor>(); object factory = ServiceProvider.GetService(typeof(Microsoft.AspNetCore.Http.IHttpContextAccessor)); // Microsoft.AspNetCore.Http.HttpContextAccessor fac =(Microsoft.AspNetCore.Http.HttpContextAccessor)factory; Microsoft.AspNetCore.Http.HttpContext context = ((Microsoft.AspNetCore.Http.HttpContextAccessor)factory).HttpContext; // context.Response.WriteAsync("Test"); return context; } } } // End Class HttpContext } 

现在,在添加IServiceProvider svp Configure中,将此服务提供者保存到刚创build的虚拟类System.Web.HttpContext(System.Web.HttpContext.ServiceProvider)中的静态variables“ServiceProvider”

并将HostingEnvironment.IsHosted设置为true

 System.Web.Hosting.HostingEnvironment.m_IsHosted = true; 

这基本上是System.Web做的,只是你从来没有看到它(我猜这个variables被声明为内部而不是公共的)。

 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider svp) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); ServiceProvider = svp; System.Web.HttpContext.ServiceProvider = svp; System.Web.Hosting.HostingEnvironment.m_IsHosted = true; app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationScheme = "MyCookieMiddlewareInstance", LoginPath = new Microsoft.AspNetCore.Http.PathString("/Account/Unauthorized/"), AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/Account/Forbidden/"), AutomaticAuthenticate = true, AutomaticChallenge = true, CookieSecure = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest , CookieHttpOnly=false }); 

就像在ASP.NET Web-Forms中一样,当你尝试访问一个没有的HttpContext的时候,你会得到一个NullReference,比如它曾经在Global.asax的Application_Start中。

我再次强调,这只有在你实际添加的情况下才有效

 services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>(); 

像我写你应该。
欢迎使用DI模式中的ServiceLocator模式;)
有关风险和副作用,请咨询您的驻地医生或药剂师 – 或者在github.com/aspnet上学习.NET Core的源代码 ,并进行一些testing。


也许更可维护的方法是添加这个辅助类

 namespace System.Web { public static class HttpContext { private static Microsoft.AspNetCore.Http.IHttpContextAccessor m_httpContextAccessor; public static void Configure(Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor) { m_httpContextAccessor = httpContextAccessor; } public static Microsoft.AspNetCore.Http.HttpContext Current { get { return m_httpContextAccessor.HttpContext; } } } } 

然后在Startup-> Configure中调用HttpContext.Configure

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider svp) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); System.Web.HttpContext.Configure(app.ApplicationServices. GetRequiredService<Microsoft.AspNetCore.Http.IHttpContextAccessor>() ); 

只是添加到其他答案…

在ASP.NET Core 2.1中,有AddHttpContextAccessor扩展方法 ,它将以正确的生命周期注册IHttpContxtAccessor

我想到的最合法的方法是在你的静态实现中注入IHttpContextAccessor,如下所示:

 public static class HttpHelper { private static IHttpContextAccessor _accessor; public static void Configure(IHttpContextAccessor httpContextAccessor) { _accessor = httpContextAccessor; } public static HttpContext HttpContext => _accessor.HttpContext; } 

然后在启动configuration中分配IHttpContextAccessor应该完成这项工作。

 HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>()); 

我想你还应该注册服务单身人士:

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();