Access the Current Httpcontext 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...
}

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

Access the current HttpContext in ASP.NET Core with Custom

Some points you need to pay attention to:

1.You class inherit from an interface and implement a GetDataFromSession method.You need to define an interface IMyComponent first and register IMyComponent in staryup if you would like use by DI

public interface IMyComponent
{
string GetDataFromSession();
}

startup.cs

services.AddSingleton<IMyComponent, MyComponent>();

2.It seems that you would like to get data from session. The "Key" represents any session name (string).You need to enable session for asp.net core and set a session value first.

_contextAccessor.HttpContext.Session.SetString("Key", "value");

3.Register IHttpContextAccessor in your startup

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

4.Full demo:

MyComponent.cs

public class MyComponent : IMyComponent
{
private readonly IHttpContextAccessor _contextAccessor;

public MyComponent(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}

public string GetDataFromSession()
{

_contextAccessor.HttpContext.Session.SetString("Key", "value");
return _contextAccessor.HttpContext.Session.GetString("Key");
}
}

public interface IMyComponent
{
string GetDataFromSession();
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();

services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
// Make the session cookie essential
options.Cookie.IsEssential = true;
});


services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IMyComponent, MyComponent>();
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//other middlewares
app.UseSession();
app.UseMvc();
}
}

API Controller:

public class ForumsController : ControllerBase
{
private readonly IMyComponent _myComponent;

public ForumsController(IMyComponent myComponent)
{
_myComponent = myComponent;
}
// GET api/forums
[HttpGet]
public ActionResult<string> Get()
{
var data = _myComponent.GetDataFromSession();//call method and return "value"
return data;

}

How to access current HttpContext in ASP.NET Core 2 Custom Policy-Based Authorization with AuthorizationHandlerContext

You should inject an instance of an IHttpContextAccessor into your AuthorizationHandler.

In the context of your example, this may look like the following:

public class BadgeEntryHandler : AuthorizationHandler<EnterBuildingRequirement>
{
IHttpContextAccessor _httpContextAccessor = null;

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

protected override Task HandleRequirementAsync(
AuthorizationContext context,
EnterBuildingRequirement requirement)
{
HttpContext httpContext = _httpContextAccessor.HttpContext; // Access context here

if (context.User.HasClaim(c => c.Type == ClaimTypes.BadgeId &&
c.Issuer == "http://microsoftsecurity"))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}

You may need to register this in your DI setup (if one of your dependencies has not already), as follows:

services.AddHttpContextAccessor();

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.

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.



Related Topics



Leave a reply



Submit