访问 ASP.NET 核心中的当前 HttpContext

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

使用经典的 ASP.NET MVC 和 System.Web,我只需要使用 HttpContext.Current来静态访问上下文。但是如何在 ASP.NET 核心中做到这一点呢?

93652 次浏览

在 ASP.NET Core 中 HttpContext.Current已经不存在了,但是有一个新的 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*);
}
}

巫师。
你可以的
迁移大块 垃圾代码的秘诀。
下面的方法是一个邪恶的黑客,积极从事撒旦的表达工作(在眼睛。NET 核心框架开发人员) ,但是很有效:

public class Startup

添加属性

public IConfigurationRoot Configuration { get; }

然后向 ConfigureServices 中的 DI 添加一个单例 IHttpContextAccessor。

    // 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 创建一个替换类:

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的地方,将这个服务提供程序保存到刚刚创建的虚拟类 System 中的静态变量“ ServiceProvider”中。韦伯。HttpContext (系统。韦伯。HttpContext.服务供应商)

并设置 HostingEnvironment. IsHosted 为 true

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

这基本上就是系统。Web 做到了,只是你从来没有看到它(我猜测变量被声明为内部的,而不是公共的)。

// 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,而实际上没有 HttpContext,就像在 global.asax 中的 Application_Start中一样。

我再强调一次,这只有在你真正加入

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

就像我写的那样。
欢迎使用 DI 模式中的 ServiceLocator 模式;)
对于风险和副作用,咨询你的住院医生或药剂师-或研究来源。NET 核心,并做了一些测试。


也许更易于维护的方法是添加这个 helper 类

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;
}
}




}




}

然后在启动-> 配置中调用 HttpContext

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

我想您还需要注册服务 singleton:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

再加上其他的答案。

在 ASP.NET Core 2.1中,有 AddHttpContextAccessor扩展方法,它将用正确的生存期注册 IHttpContextAccessor:

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();


// Other code...
}
}

根据这篇文章: 在 ASP.NET 核心框架组件之外访问 HttpContext

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

要在类构造函数中访问会话对象而不显式使用依赖注入,请按照下列步骤操作:

  1. 在 Startup.cs (ConfigureServices)上添加一个 Singleton 实例:

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
  2. 在目标类中声明 HttpContextAccessor 的实例:

    IHttpContextAccessor _httpContextAccessor = new HttpContextAccessor();
    
  3. 访问会话对象:

    string mySessionVar = _httpContextAccessor.HttpContext.Session.GetString("_MySessionVar");
    

例子

Startup.cs

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");
}
}
}

享受:)