I have problem when I'm trying to get httpcontext from IHttpContextAccessor field is always null in class.
There is my startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDistributedMemoryCache();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<IUserContextServices, UserContextService>();
services.AddSession(options =>
{
options.Cookie.Name = ".AdventureWorks.Session";
options.IdleTimeout = TimeSpan.FromSeconds(10);
});
}
This is My UserContext Class which implements IUserContext interface
public class UserContextService : IUserContextServices
{
private readonly IHttpContextAccessor contextAccessor;
PQADBContext _context = new PQADBContext();
public UserContextService(IHttpContextAccessor accessor)
{
contextAccessor = accessor;
}
public UserContextService()
{
}
public HttpContext Context
{
get
{
return contextAccessor.HttpContext;
}
}
public int UserID()
{
return Context.Session.GetID("UserID").ConvertToInt();
}
public bool isLogin()
{
return Context.Session.GetBoolean("isLogin").ConvertToBool();
}
public UserAccount CreateSession(LoginViewModel logindata, bool EncryptPwd = true)
{
string error;
error = "";
try
{
string EncPwd = EncryptPwd ? EncryptDecryptHelper.Encrypt(logindata.Password) : logindata.Password;
var UserDetail =_context.UserAccount.Where(e => e.P_No == logindata.PNo && e.Password == EncPwd).SingleOrDefault();
if (UserDetail != null)
{
//HttpContext.Session.SetInt32()
// ///put all the properties in session variables
Context.Session.SetBoolean("isLogin", true);
Context.Session.SetID("UserID",UserDetail.AccountId);
Context.Session.SetID("P_No",Convert.ToInt32(UserDetail.P_No));
Context.Session.SetBoolean("isActive", true);
Context.Session.SetBoolean("Email", true);
Context.Session.SetID("RoleId", 1);
Context.Session.SetString("userName", "admin");
}
httpContext available in above class and also set the Session values but when i try to access httpcontext in this class it gives me null object reference
public class UserService
{
private readonly IHttpContextAccessor contextAccessor;
public IUserContextServices _userContext = new UserContextService();
public UserService()
{
}
public bool CreateEmployee(AppEmployees appemployee, int RoleId, bool isEmailSend, out string error)
{
appemployee.CreatedBy = _userContext.UserID(); //this line shows null reference exception
appemployee.CreatedDate = DateTime.Now;
}
You are newing up the UserContextService
using the parameterless constructor
public IUserContextServices _userContext = new UserContextService();
instead of relying on Dependency Injection.
You need to configure your UserService
to be used with your DI container - via constructor injection that would be
public class UserService
{
private readonly IUserServiceContext _userServiceContext;
public UserService(IUserServiceContext userServiceContext)
{
_userServiceContext = userServiceContext;
}
}
You will also need to amend your Startup.cs to register the UserService
and you may want it to implement an interface too
Why do you use default constructor in your UserService?
You use next code:
public IUserContextServices _userContext = new UserContextService();
Of course here you have null for IHttpContextAccessor
.
You need to use DI in your UserService.
Example:
private readonly IUserContextService _userContextService;
public UserService(IUserContextService userContextService)
{
_userContextService = userContextService;
}
There is good post about DI in .NET Core.
If you have set UserId directly as
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
}
This way you might get null UserId most of the time instead create httpContextAccessor field first like
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public string UserId { get { return httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); } }
Then get UserId, this way the problem of getting null UserId will be resolved.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.