Reputation: 1293
I am trying to use HttpContextAccessor on my custom class(BLL class) and while i succesfully initializes the ContextAccessor meantime HttpContext itself is null.
Code in program.cs
builder.Services.AddSingleton<IUserPermissionConfig, UserPermisionConfig>();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
var setUserPermission = app.Services.GetRequiredService<IUserPermissionConfig>();
setUserPermission.SetUserPermissionsSession(UserConstants.SYSTEM_ID);
UserPermisionConfig component code
private readonly IHttpContextAccessor _httpContextAccessor;
public UserPermisionConfig( IHttpContextAccessor httpContextAccessor)
{
_permisionServiceClient = new PermissionServiceClient();
_httpContextAccessor = httpContextAccessor ?? throw new Exception("Http context accessor is null.");
}
public async Task SetUserPermissionsSession(int systemId)
{
string userName = _httpContextAccessor.HttpContext.
User.Identity.Name; //here httpcontext is alway null
UserPermissionsModel userPermissionModel = await GetUserPermission(systemId, userName);
_httpContextAccessor.HttpContext.Session.Set(UserConstants.SESSION_USER_PERMISSIOS, ByteArrayExtensions.ToByteArray(userPermissionModel));
}
Any help ?
Upvotes: 0
Views: 9043
Reputation: 11924
I think you could check this document
just as mentioned in the document:
HttpContext isn't thread-safe. Reading or writing properties of the HttpContext outside of processing a request can result in a NullReferenceException.
In Asp.net if you call httpcontext directly in Application_Start()
method in global.asax.cs,you would get the similar error
If your codes was in your HttpModule in Asp.net ,check this document to learn how to migrate module codes to middleware
And I tried as below:
public class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly IUserPermisionConfig _config;
public MyMiddleware(RequestDelegate next, IUserPermisionConfig config)
{
_next = next;
_config = config;
}
public async Task InvokeAsync(HttpContext context)
{
_config.SetUserPermissionsSession(5);
await _next(context);
}
}
public interface IUserPermisionConfig
{
Task SetUserPermissionsSession(int systemId);
}
public class UserPermisionConfig : IUserPermisionConfig
{
private readonly IHttpContextAccessor _accessor;
public UserPermisionConfig(IHttpContextAccessor accessor)
{
_accessor = accessor;
}
public Task SetUserPermissionsSession(int systemId)
{
var httpcontext = _accessor.HttpContext;
var user = httpcontext.User.Identity?.Name;
httpcontext.Session.SetString("Somekey", systemId.ToString());
return Task.CompletedTask;
}
}
Regist the services:
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserPermisionConfig, UserPermisionConfig>();
// The two following services are required to use session in asp.net core
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
call the middleware in the pipeline :
.....
app.UseSession();
app.UseMiddleware<MyMiddleware>();
.....
it works well in my case:
Upvotes: 2
Reputation: 2360
Ok, it looks like you are trying to access the HTTP context directly from Program.cs
. This is not how it works.
The HTTP context is only avialable during an incoming HTTP request.
Your IUserPermissionConfig
service must be called from the ASP.net pipeline somewhere (controller, filter, middleware).
Upvotes: 0