Welcome to today’s post.
In today’s post I will show how to use the http context within an ASP.NET Core application.
When we want to access the security context of an incoming HTTP web request, in legacy web applications using .NET 4.x Framework and earlier, the accepted approach is to access the HttpRequest object, then access the Context property. In turn, the Context property, contains the User property, which contains details relating to the user that is authenticated within the incoming web request.
When we use the .NET Core framework (versions 2.0, 3.1 and onwards) to build our web application or web API service, the traditional approach to accessing the user context, HttpRequest.Context no longer works as expected in all application contexts.
In what Application Contexts is HttpRequest accessible?
The main reason why the traditional approach does not work in all contexts is that when we are accessing the http context within a custom service that does not have the HTTP request and response flow, the value of the context is null.
What we do know is that ASP.NET Core components, that are part of the HTTP request and response flow, the http request can be read from a property that is included within the component. With the ASP.NET Core Controller class, there is a built-in property HttpContext from the ControllerBase base class. Within a derived controller class, we can access the context as follows:
HttpContext.Request
Likewise, with a web application built with ASP.NET Core Razor Pages, the PageModel class also has the built-in property, HttpContext which allows us to access the Request property as can do within controllers. From Razor CSHTML markup, there is a built-in Context property that is accessible.
In which Application Contexts will HttpContext not work as expected?
Unlike the above contexts, where the HTTP request and response flows have properties that support a populated HttpRequest object, custom classes that we create and instantiate within the application that are outside of the HTTP request and response pipeline do not have properties to support retrieval of the HttpContext property within the HttpRequest.
To supply a valid HttpContext into a custom class, we will need to inject an instance of the http context into constructor of the custom class. Before we can inject an instance of the http context into the custom class, we will need to add the IHttpContextAccessor service into the application’s service collection in the startup sequence. I will show how to do this in the next section.
How to Setup and use IHttpContextAccessor within your Application
In the first section, I mentioned that HttpRequest.Context only reliably works within the context of ASP.NET Core web components such as a Razor page or a Controller. (e.g. using Context.User.Identity) or controller (HttpContext.Request).
To access the HttpContext within custom classes and services within your application, you will need to make use of the IHttpContextAccessor interface of .NET Core (versions 2.0 onwards).
I will now show how to use IHttpContextAccessor within your application and how to set it up in the startup.
Open your Startup.cs file, then apply the following source additions:
Add the following namespace:
using Microsoft.AspNetCore.Http;
In your ConfigureServices() method, add the line shown:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
This will inject the context accessor interface into the services container and make it available to your classes within the context of the application.
To use the above context accessor in your class, follow the tasks that I show with code excerpts below:
Step 1. Declare the namespace:
using Microsoft.AspNetCore.Http;
Step 2. Setup dependencies in your class:
Include a member of type HttpContext within your class as shown:
public class ReportService: IReportService
{
ApplicationDbContext _db;
..
UserManager<ApplicationUser> _userManager;
HttpContext _context;
Step 3. Pass the http context accessor interface to your constructor:
public ReportService(ApplicationDbContext db,
UserManager<ApplicationUser> userManager,
IHttpContextAccessor httpContextAccessor,…)
Step 4. Assign the http context interface to your accessor context within your constructor:
Assign the HttpContext class member object to the HttpContext property of the http context accessor object.
public ReportService(ApplicationDbContext db,
UserManager<ApplicationUser> userManager,
IHttpContextAccessor httpContextAccessor, ..)
{
_db = db;
..
_context = httpContextAccessor.HttpContext;
}
...
Step 5. Access the context within a method.
public async Task<List<BookLoan.Models.LoanReportViewModel>> MyOnLoanReport()
{
string curruser = _context.User.Identity.Name;
return await OnLoanReport(curruser);
}
Once the above tasks are completed and your application is run, you will find that the current authenticated user details will be accessible within your custom class.
The use of the http context accessor service is commonly used within a Web API service or Microservice where we have not wired the controller middleware service. When the API service endpoints are requested through any web client or service that passes in an authenticated account through the HTTP request, the context of the request is then injected into the class for each API method request.
That’s all for today’s post.
I hope you have found this a useful and informative post.
Andrew Halil is a blogger, author and software developer with expertise of many areas in the information technology industry including full-stack web and native cloud based development, test driven development and Devops.