How to Get Httpcontext.Current in ASP.NET Core

How to get HttpContext.Current in ASP.NET Core?

As a general rule, converting a Web Forms or MVC5 application to ASP.NET Core will require a significant amount of refactoring.

HttpContext.Current was removed in ASP.NET Core. Accessing the current HTTP context from a separate class library is the type of messy architecture that ASP.NET Core tries to avoid. There are a few ways to re-architect this in ASP.NET Core.

HttpContext property

You can access the current HTTP context via the HttpContext property on any controller. The closest thing to your original code sample would be to pass HttpContext into the method you are calling:

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're writing custom middleware for the ASP.NET Core pipeline, the current request's HttpContext is passed into your Invoke method automatically:

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

HTTP context accessor

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

Request this interface in your constructor:

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

You can then access the current HTTP context in a safe way:

var context = _httpContextAccessor.HttpContext;
// Do something with the current HTTP context...

IHttpContextAccessor isn't always added to the service container by default, so register it in ConfigureServices just to be safe:

public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// if < .NET Core 2.2 use this
//services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

// Other code...
}

Httpcontext.current in ASP.NET Core API

HttpContext used to be a static sealed class, which was horrendous for testing. In ASP.NET Core, it is now scoped to the request (i.e. it is instantiated at the beginning of the request and disposed at the end of the request). As such, there's no such thing as HttpContext.Current because 1) it's not a static any more and 2) it doesn't exist outside the request pipeline.

In order to access the current (i.e. in scope) HttpContext instance, you must inject IHttpContextAccessor. That's a singleton which must additionally be registered with the service collection if you need to make use of it:

services.AddHttpContextAccessor();

Then, in your library class, you'd simply do something like:

public class MyClass
{
private readonly IHttpContextAccessor _httpContextAccessor;

public MyClass(IHttpContextAccesor httpContextAccesor)
{
_httpContextAccesor = httpContextAccessor;
}

...
}

And later:

// WARNING: may be null
var httpContext = _httpContextAccessor.HttpContext;

As I said previously, HttpContext only exists within the request pipeline, so you can only access it in code that is running in that scope. If you try to get it in code that is running not as a direct result of a request coming into your an ASP.NET Core app, then it will simply be null. As such, you should do proper null checking to ensure you can safely use it.

Access the current HttpContext in ASP.NET Core

HttpContext.Current doesn't exist anymore in ASP.NET Core but there's a new IHttpContextAccessor that you can inject in your dependencies and use to retrieve 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*);
}
}

Accessing HttpContext in ASP.NET Core 2.2 Class library

Register IHttpContextAccessor in the Startup class as follows:

public void ConfigureServices(IServiceCollection services)
{
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

// Or you can also register as follows

services.AddHttpContextAccessor();
}

Then in your class libray

public class Test 
{
private IHttpContextAccessor _httpContextAccessor;
public Test(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Foo()
{
_httpContextAccessor.HttpContext.Request.Path..
}
}

Asp.Net Core 2.x HttpContext.Current not really available

The problem is, you are currently using it wrong.

Inside Controller it seems the easiest, but most of this HttpContext.Current stuff is sprinkled around various places domain libraries etc..

A Domain Libarary should be independent from the frontend. It just doesn't matter if it's a website with Session or a statefull WPF App. Or a RestFull Api.

That said, a relative Quick Fix would be to inject the HttpContext into your domain class.

public DomainService(IHttpContextAccessor httpContext)
{
_httpContext = httpContext;
}

You can then obtain your DomainService via Dependency Injection. If the creation is complex, you are looking for a Factory.

Or you could create the Service yourself in your ActionMethod (Of course in this case you need need to change the constructor of the Service to HttpContext:

public IActionResult Foo()
{
var service = new DomainService(HttpContext)
}

That said: it was removed for a reason. Please do not rely on HttpContext in your Domain! Create a business object and give it as parameter to the domain instead.


Not sure if it is the best way, but I have created a BusinessContext class and registered it as scoped. A factory is responsible for creating it with the needed data.



DON'T DO THIS:

If you are really crazy, maybe this could help you for migration.

.net core 3.1 How to add HttpContext.Current and HttpContext.Current.Application[ ]

First, register the service in Startup.cs,

services.AddHttpContextAccessor();

Then you can call below code in any class, it replaces HttpContext.Current

private HttpContext _httpContext => new HttpContextAccessor().HttpContext;

You can use _httpContext.Items[] instead of Application. (Test this before production)

how to use HttpContext.Current in net core 5 (no necromenssing)

Inject the IHttpContextAccessor type and read its HttpContext property.



Related Topics



Leave a reply



Submit