如何获得ASP.NET核心中的HttpContext.Current?
我们目前正在使用ASP.NET Core重写/转换我们的ASP.NET WebForms应用程序。 尽量避免重新devise。
有一个部分我们在类库中使用HttpContext来检查当前状态。 如何在.NET Core 1.0中访问HttpContext.Current ? 
  var current = HttpContext.Current; if (current == null) { // do something here // string connection = Configuration.GetConnectionString("MyDb"); } 
我需要访问这个为了构build当前的应用程序主机。
 $"{current.Request.Url.Scheme}://{current.Request.Url.Host}{(current.Request.Url.Port == 80 ? "" : ":" + current.Request.Url.Port)}"; 
	
作为一般规则,将Web窗体或MVC5应用程序转换为ASP.NET Core 将需要大量的重构。
 获取HttpContext.Current是不可能的,因为在ASP.NET Core中删除了Current 。 从单独的类库访问当前HTTP上下文是ASP.NET Core试图避免的混乱体系结构的types。 
 在ASP.NET Core中,可以使用HttpContext从控制器访问当前HTTP上下文。 最接近你原来的代码示例是将HttpContext传递给你正在调用的方法: 
 public class HomeController : Controller { public IActionResult Index() { MyMethod(HttpContext); // Other code } } public void MyMethod(Microsoft.AspNetCore.Http.HttpContext context) { var host = $"{context.Request.Scheme}://{context.Request.Host}"; // Other code } 
 也可以使用ASP.NET Coredependency injection系统中的IHttpContextAccessor获取上下文。 如果您有一个从服务容器请求接口的控制器或中间件function: 
 public MyMiddleware(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } 
然后您可以安全地访问当前的HTTP上下文:
 var context = _httpContextAccessor.HttpContext; 
 由于默认情况下IHttpContextAccessor未被添加到服务容器,因此您必须注册它: 
 public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // Other code... } 
  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>() ); 
如果你真的需要静态访问当前的上下文,有一个解决scheme。 在Startup.Configure(…。)
 app.Use(async (httpContext, next) => { CallContext.LogicalSetData("CurrentContextKey", httpContext); try { await next(); } finally { CallContext.FreeNamedDataSlot("CurrentContextKey"); } }); 
而当你需要它时,你可以得到它:
 HttpContext context = CallContext.LogicalGetData("CurrentContextKey") as HttpContext; 
我希望有帮助。 请记住,这个解决方法是当你没有select。 最好的做法是使用dedependency injection。