【问题标题】:IHttpContextAccessor is null in classIHttpContextAccessor 在类中为空
【发布时间】:2018-02-28 14:39:10
【问题描述】:

当我尝试从 IHttpContextAccessor 获取 httpcontext 时遇到问题,类中的字段始终为 null。

这是我的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);
    });
}

这是实现 IUserContext 接口的我的 UserContext 类

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 在上述类中可用,并且还设置了 Session 值,但是当我尝试访问此类中的 httpcontext 时,它给了我空对象引用

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

【问题讨论】:

    标签: c# asp.net asp.net-core-2.0 httpcontext


    【解决方案1】:

    您正在使用无参数构造函数更新UserContextService

    public IUserContextServices _userContext = new UserContextService();
    

    而不是依赖依赖注入。

    您需要配置 UserService 以与您的 DI 容器一起使用 - 通过构造函数注入将是

    public class UserService
    {
        private readonly IUserServiceContext _userServiceContext;
    
        public UserService(IUserServiceContext userServiceContext)
        {
            _userServiceContext = userServiceContext;
        }
    }
    

    您还需要修改您的 Startup.cs 以注册 UserService,并且您可能希望它也实现一个接口

    【讨论】:

      【解决方案2】:

      为什么在 UserService 中使用默认构造函数?

      你使用下一个代码:

      public IUserContextServices _userContext = new UserContextService();
      

      当然,IHttpContextAccessor 是 null。

      您需要在 UserService 中使用 DI。

      例子:

      private readonly IUserContextService _userContextService;
      public UserService(IUserContextService userContextService)
      {  
          _userContextService = userContextService;
      }
      

      关于 .NET Core 中的 DI 有很好的 post。

      【讨论】:

      • 我需要访问任何班级的当前会话,我该怎么做?我的意思是如何在任何类中调用 IhttpContextAccessor?
      • @AfaqRajput 您需要通过构造函数使用注入。这是在必要类中检索 IHttpContextAccessor 的最简单方法(如答案中所述)。您也可以使用Autofac 进行属性注入。在这种情况下,您可以使用 IHttpContextAccessor 作为公共属性。
      【解决方案3】:

      如果你已经将UserId直接设置为

      public CurrentUserService(IHttpContextAccessor httpContextAccessor)
      {
          UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
      }
      

      这样你可能会得到 null UserId 大多数时间而不是先创建 httpContextAccessor 字段

      public CurrentUserService(IHttpContextAccessor httpContextAccessor)
      {
           this.httpContextAccessor = httpContextAccessor;
      }
      public string UserId { get { return httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); } }
      

      然后获取UserId,这样就解决了获取null UserId的问题。

      【讨论】:

        猜你喜欢
        • 2020-06-11
        • 2017-11-04
        • 2021-05-10
        • 2022-07-07
        • 1970-01-01
        • 2021-02-08
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        相关资源
        最近更新 更多