访问 ASP.NET 核心中的当前 HttpContext
Access the current HttpContext in ASP.NET Core
我需要在静态方法或实用程序服务中访问当前 HttpContext
。
使用经典的 ASP.NET MVC 和 System.Web
,我将只使用 HttpContext.Current
来静态访问上下文。但是我如何在 ASP.NET Core 中执行此操作?
HttpContext.Current
不再存在于 ASP.NET 核心中,但是有一个新的 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*);
}
}
死灵法术。
是的,你可以
那些迁移大量 junks 代码块(叹气,弗洛伊德式失误)代码的秘密提示。
以下方法是一个黑客的邪恶的痈肿,积极从事撒旦的快速工作(在 .NET Core 框架开发人员的眼中),但它有效:
在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>();
然后在配置
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 创建一个替换 class:
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
}
现在在 Configure 中,您在其中添加了 IServiceProvider svp
,将此服务提供商保存到刚刚创建的虚拟 class System.Web.HttpContext 中的静态变量 "ServiceProvider" 中( System.Web.HttpContext.ServiceProvider)
并将 HostingEnvironment.IsHosted 设置为真
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
这基本上就是 System.Web 所做的,只是您从未见过它(我猜该变量被声明为内部变量而不是 public)。
// 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 表单中一样,当您尝试访问存在 none 的 HttpContext 时,您将获得一个 NullReference,例如它曾经在 [=23] =] 在 global.asax.
我再次强调,这只有在您实际添加
时才有效
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
就像我写给你的那样。
欢迎使用 DI 模式中的 ServiceLocator 模式 ;)
对于风险和副作用,请咨询您的住院医生或药剂师 - 或者在 github.com/aspnet 上研究 .NET Core 的来源,并进行一些测试。
也许更易于维护的方法是添加此助手 class
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>()
);
我想到的最合法的方法是在静态实现中注入 IHttpContextAccessor,如下所示:
public static class HttpHelper
{
private static IHttpContextAccessor _accessor;
public static void Configure(IHttpContextAccessor httpContextAccessor)
{
_accessor = httpContextAccessor;
}
public static HttpContext HttpContext => _accessor.HttpContext;
}
然后在启动配置中分配 IHttpContextAccessor 应该可以完成工作。
HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
我猜你还需要注册服务单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
只是添加到其他答案...
在 ASP.NET Core 2.1 中,有 the AddHttpContextAccessor
extension method,它将用正确的生命周期注册 IHttpContextAccessor
:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// Other code...
}
}
根据这篇文章:Accessing HttpContext outside of framework components in ASP.NET Core
namespace System.Web
{
public static class HttpContext
{
private static IHttpContextAccessor _contextAccessor;
public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext;
internal static void Configure(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
}
}
然后:
public static class StaticHttpContextExtensions
{
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
{
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
System.Web.HttpContext.Configure(httpContextAccessor);
return app;
}
}
然后:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticHttpContext();
app.UseMvc();
}
}
你可以这样使用它:
using System.Web;
public class MyService
{
public void DoWork()
{
var context = HttpContext.Current;
// continue with context instance
}
}
正在启动中
services.AddHttpContextAccessor();
在控制器中
public class HomeController : Controller
{
private readonly IHttpContextAccessor _context;
public HomeController(IHttpContextAccessor context)
{
_context = context;
}
public IActionResult Index()
{
var context = _context.HttpContext.Request.Headers.ToList();
return View();
}
}
要从 class 访问会话对象而不在 class 构造函数中显式使用依赖注入,请按照以下步骤操作:
在 Startup.cs (ConfigureServices) 上添加单例实例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在您的目标中 class 声明一个 HttpContextAccessor 实例:
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
访问会话对象:
string mySessionVar = _httpContextAccessor.HttpContext.Session.GetString("_MySessionVar");
示例
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
YourClass.cs
public class YourClass {
public string yourProperty {
get{
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
return _httpContextAccessor.HttpContext.Session.GetString("_YourSessionVar");
}
}
}
尽情享受吧:)
我需要在静态方法或实用程序服务中访问当前 HttpContext
。
使用经典的 ASP.NET MVC 和 System.Web
,我将只使用 HttpContext.Current
来静态访问上下文。但是我如何在 ASP.NET Core 中执行此操作?
HttpContext.Current
不再存在于 ASP.NET 核心中,但是有一个新的 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*);
}
}
死灵法术。
是的,你可以
那些迁移大量 junks 代码块(叹气,弗洛伊德式失误)代码的秘密提示。
以下方法是一个黑客的邪恶的痈肿,积极从事撒旦的快速工作(在 .NET Core 框架开发人员的眼中),但它有效:
在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>();
然后在配置
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 创建一个替换 class:
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
}
现在在 Configure 中,您在其中添加了 IServiceProvider svp
,将此服务提供商保存到刚刚创建的虚拟 class System.Web.HttpContext 中的静态变量 "ServiceProvider" 中( System.Web.HttpContext.ServiceProvider)
并将 HostingEnvironment.IsHosted 设置为真
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
这基本上就是 System.Web 所做的,只是您从未见过它(我猜该变量被声明为内部变量而不是 public)。
// 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 表单中一样,当您尝试访问存在 none 的 HttpContext 时,您将获得一个 NullReference,例如它曾经在 [=23] =] 在 global.asax.
我再次强调,这只有在您实际添加
时才有效services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
就像我写给你的那样。
欢迎使用 DI 模式中的 ServiceLocator 模式 ;)
对于风险和副作用,请咨询您的住院医生或药剂师 - 或者在 github.com/aspnet 上研究 .NET Core 的来源,并进行一些测试。
也许更易于维护的方法是添加此助手 class
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.Configurepublic 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>()
);
我想到的最合法的方法是在静态实现中注入 IHttpContextAccessor,如下所示:
public static class HttpHelper
{
private static IHttpContextAccessor _accessor;
public static void Configure(IHttpContextAccessor httpContextAccessor)
{
_accessor = httpContextAccessor;
}
public static HttpContext HttpContext => _accessor.HttpContext;
}
然后在启动配置中分配 IHttpContextAccessor 应该可以完成工作。
HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
我猜你还需要注册服务单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
只是添加到其他答案...
在 ASP.NET Core 2.1 中,有 the AddHttpContextAccessor
extension method,它将用正确的生命周期注册 IHttpContextAccessor
:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// Other code...
}
}
根据这篇文章:Accessing HttpContext outside of framework components in ASP.NET Core
namespace System.Web
{
public static class HttpContext
{
private static IHttpContextAccessor _contextAccessor;
public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext;
internal static void Configure(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
}
}
然后:
public static class StaticHttpContextExtensions
{
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
{
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
System.Web.HttpContext.Configure(httpContextAccessor);
return app;
}
}
然后:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticHttpContext();
app.UseMvc();
}
}
你可以这样使用它:
using System.Web;
public class MyService
{
public void DoWork()
{
var context = HttpContext.Current;
// continue with context instance
}
}
正在启动中
services.AddHttpContextAccessor();
在控制器中
public class HomeController : Controller
{
private readonly IHttpContextAccessor _context;
public HomeController(IHttpContextAccessor context)
{
_context = context;
}
public IActionResult Index()
{
var context = _context.HttpContext.Request.Headers.ToList();
return View();
}
}
要从 class 访问会话对象而不在 class 构造函数中显式使用依赖注入,请按照以下步骤操作:
在 Startup.cs (ConfigureServices) 上添加单例实例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在您的目标中 class 声明一个 HttpContextAccessor 实例:
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
访问会话对象:
string mySessionVar = _httpContextAccessor.HttpContext.Session.GetString("_MySessionVar");
示例
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
YourClass.cs
public class YourClass {
public string yourProperty {
get{
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
return _httpContextAccessor.HttpContext.Session.GetString("_YourSessionVar");
}
}
}
尽情享受吧:)