C# 访问ASP.NET核心中的当前HttpContext
我需要在静态方法或实用程序服务中访问当前的C# 访问ASP.NET核心中的当前HttpContext,c#,asp.net-core,C#,Asp.net Core,我需要在静态方法或实用程序服务中访问当前的HttpContext 使用经典的ASP.NET MVC和System.Web,我只需使用HttpContext.Current静态访问上下文。但是如何在ASP.NET Core中做到这一点呢?HttpContext。当前的在ASP.NET Core中不再存在,但有一个新的,您可以将其注入依赖项中,并用于检索当前的HttpContext: public class MyComponent : IMyComponent { private read
HttpContext
使用经典的ASP.NET MVC和
System.Web
,我只需使用HttpContext.Current
静态访问上下文。但是如何在ASP.NET Core中做到这一点呢?HttpContext。当前的
在ASP.NET Core中不再存在,但有一个新的,您可以将其注入依赖项中,并用于检索当前的HttpContext
:
public class MyComponent : IMyComponent
{
private readonly IHttpContextAccessor _contextAccessor;
public MyComponent(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public string GetDataFromSession()
{
return _contextAccessor.HttpContext.Session.GetString(*KEY*);
}
}
巫术是的,你可以
为那些迁移大块代码(叹气,弗洛伊德式的错误)的人提供的秘密提示。
下面的方法是一个黑客的邪恶毒瘤,该黑客正在积极执行撒旦(在.NET核心框架开发人员眼中)的快速工作,但它有效: 在
公共类启动中
添加属性
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>();
添加DI参数IServiceProvider svp,使该方法如下所示:
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
,IServiceProvider svp)
{
接下来,为System.Web创建替换类:
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
}
这基本上就是System.Web所做的,只是您从未见过它(我猜该变量被声明为内部变量而不是公共变量)
与ASP.NET Web表单中一样,当您尝试访问一个HttpContext时,如果没有HttpContext,则会得到一个空引用,例如它以前在global.asax中的Application\u Start
中
我再次强调,只有当你真的添加了
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
然后在启动->配置中调用HttpContext.Configure
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
)
{
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>()
);
public void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂、IServiceProvider svp)
{
loggerFactory.AddConsole(Configuration.GetSection(“Logging”);
loggerFactory.AddDebug();
System.Web.HttpContext.Configure(app.ApplicationServices)。
GetRequiredService()
);
我想到的最合法的方法是在静态实现中注入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>());
HttpHelper.Configure(app.ApplicationServices.GetRequiredService());
我想您还需要注册服务singleton:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton();
只需添加到其他答案中
在ASP.NET Core 2.1中,将使用正确的生存期注册IHttpContextAccessor
:
公共类启动
{
public void配置服务(IServiceCollection服务)
{
AddHttpContextAccessor();
//其他代码。。。
}
}
根据本文:
然后:
您可以这样使用它:
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();
}
}
要从类访问会话对象而不在类构造函数中显式使用依赖项注入,请执行以下步骤:
string mySessionVar = _httpContextAccessor.HttpContext.Session.GetString("_MySessionVar");
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public class YourClass {
public string yourProperty {
get{
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
return _httpContextAccessor.HttpContext.Session.GetString("_YourSessionVar");
}
}
}
享受:)这一点很好!值得一提的是,
IHttpContextAccessor
仅在DI容器解析实例的地方可用。@tugberk好吧,理论上,您也可以使用CallContextServiceLocator
解析服务,即使是从非注入DI的实例:CallContextServiceLocator.Locator.ServiceProvider.GetService()
。实际上,如果可以避免,这是一件好事:)不要使用CallContextServiceLocator@davidfowl除非你有一个有效的技术理由(当然除了“静态是邪恶的”之外),我打赌人们会在没有其他选择的情况下使用它。当然,人们很少有有效的技术理由。这更像是使用静态更容易,而且谁关心可测试性:)这是一个纯粹的问题,带有helper方法的版本在每种情况下都能正常工作。考虑多线程、异步和IoC容器中的服务不同的一生?我知道我们都必须指出这是多么邪恶…但是如果你把一个巨大的项目移植到核心,在那里HttpContext.Current被用在一些难以达到的静态类中…这可能会非常有用。我说过了。这是纯粹的邪恶…我要解释的是适当的我喜欢DI和IoC…但我正在处理一个带有邪恶静态变量的邪恶静态类的遗留应用程序,我们需要使用Kestrel推送并尝试注入HttpContext,这对我们来说是不可撤销的,不会破坏一切。是的,这是迁移的正确答案。;)很高兴看到一个更正式的替代方案对于撒旦红玉!@Ken Lyon:;)khellang:Singleton是正确的生命周期。作用域将是错误的。或者至少在撰写本文时是错误的。但是如果AddHttpContextAccessor正确地执行它,而不需要我们对特定框架版本的引用,那就更好了。你能分享一个例子吗?@Toolkit添加了一些示例MPE代码。不确定它在上面的文本中提供了什么价值。工作起来很有魅力-谢谢!
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();
}
}
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
string mySessionVar = _httpContextAccessor.HttpContext.Session.GetString("_MySessionVar");
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public class YourClass {
public string yourProperty {
get{
IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
return _httpContextAccessor.HttpContext.Session.GetString("_YourSessionVar");
}
}
}