Access the current HttpContext in the ASP.NET core

I need to access the current HttpContext in a static or utility service.

With classic ASP.NET MVC and System.Web I would simply use HttpContext.Current to access the context statically. But how to do it in ASP.NET Core?

+101
c # asp.net-core
Jul 06 '15 at 10:08
source share
8 answers

HttpContext.Current no longer exists in ASP.NET Core, but there is a new IHttpContextAccessor which you can IHttpContextAccessor in your dependencies and use to get the current HttpContext :

 public class MyComponent : IMyComponent { private readonly IHttpContextAccessor _contextAccessor; public MyComponent(IHttpContextAccessor contextAccessor) { _contextAccessor = contextAccessor; } public string GetDataFromSession() { return _contextAccessor.HttpContext.Session.GetString(*KEY*); } } 
+117
Jul 06 '15 at 10:37
source

Necromancing.

YES YOU CAN Secret advice for those who carry large chunks (sigh, Freudian slip) of code.
The next method is the evil hacking carbuncle, which is actively involved in the express work of Satan (in the eyes of the developers of the .NET Core platform) , but it works :

In public class Startup

add property

 public IConfigurationRoot Configuration { get; } 

And then add the singleton IHttpContextAccessor to the DI in ConfigureServices.

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

Then in Configure

  public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ) { 

add the DI parameter IServiceProvider svp , so the method looks like this:

  public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ,IServiceProvider svp) { 

Then create a replacement class for 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 } 

Now in Configure, where you added IServiceProvider svp , save this service provider in the static variable "ServiceProvider" of the newly created dummy class System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)

and set HostingEnvironment.IsHosted to true

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

this is essentially what System.Web did, you just never saw it (I think the variable was declared as internal, not 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 }); 

As in ASP.NET Web-Forms, you will get NullReference when you try to access the HttpContext when it is not there, for example, it was used in Application_Start in global.asax.

I emphasize again: this only works if you really added

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

as I wrote, you must.

Welcome to the ServiceLocator template in the DI template;)
For risks and side effects, contact your resident physician or pharmacist or study the .NET Core sources at github.com/aspnet and perform some tests.




Perhaps a more supported method will add this helper 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; } } } } 

And then call HttpContext.Configure in Startup-> 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>() ); 
+24
Oct 13 '16 at 18:59
source

Just to add to the other answers ...

ASP.NET Core 2.1 has an AddHttpContextAccessor extension that registers an IHttpContextAccessor with the correct lifetime.

+20
Oct 03 '17 at 10:28
source

The most legitimate way I came across was to embed an IHttpContextAccessor into your static implementation as follows:

 public static class HttpHelper { private static IHttpContextAccessor _accessor; public static void Configure(IHttpContextAccessor httpContextAccessor) { _accessor = httpContextAccessor; } public static HttpContext HttpContext => _accessor.HttpContext; } 

Then assigning IHttpContextAccessor to Startup Configure should complete the job.

 HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>()); 

I think you also need to register a singleton service:

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
+11
30 Jul. '17 at 20:30
source

According to this article: Accessing HttpContext outside of the 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; } } } 

Then:

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

Then:

 public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHttpContextAccessor(); } public void Configure(IApplicationBuilder app) { app.UseStaticHttpContext(); app.UseMvc(); } } 

You can use it like this:

 using System.Web; public class MyService { public void DoWork() { var context = HttpContext.Current; // continue with context instance } } 
+3
Jan 30 '19 at 10:52
source

Converting a Web Forms or MVC5 to ASP.NET Core will MVC5 require a significant amount of refactoring.

HttpContext.Current been removed in ASP.NET Core . Accessing the current HTTP context from a separate class library is a type of dirty architecture that ASP.NET Core trying to avoid. There are several ways to rebuild this in ASP.NET Core .

HttpContext Property

You can access the current HTTP context through the HttpContext property on any controller. The one closest to your original HttpContext code will pass the HttpContext to the method you call:

 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 } 

HttpContext parameter in middleware

If you are writing a custom middleware for an ASP.NET Core pipeline, the current HttpContext request HttpContext passed to your Invoke method:

 public Task Invoke(HttpContext context) { // Do something with the current HTTP context... } 

HTTP context accessor

Finally, you can use the IHttpContextAccessor helper service to retrieve the HTTP context in any class that is controlled by the ASP.NET Core dependency injection system. This is useful when you have a shared service used by your controllers.

Request this interface in your constructor:

 public MyMiddleware(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } 

Then you can access the current HTTP context in a safe way:

 var context = _httpContextAccessor.HttpContext; 

// Do something with the current HTTP context ... IHttpContextAccessor not always added to the default service container, so register it with ConfigureServices just for security:

 public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // Other code... } 
0
Jun 08 '19 at 6:37
source

Just add this just in case someone has some huge enterprise application that they convert to the .net core, where HttpContext.Current is everywhere, but if you are trying to do it statically and looking for a way to emulate it in .netcore This is the solution here, but I do not recommend doing this if you don’t.

https://www.strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/

0
Jun 20 '19 at
source

At launch

 services.AddHttpContextAccessor(); 

In the controller

 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(); } } 
0
Jul 13 '19 at 5:25
source



All Articles