在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>();