【问题标题】:HttpContext is null asp net core 6HttpContext 为 null asp net core 6
【发布时间】:2022-11-15 14:27:16
【问题描述】:

我正在尝试在我的自定义类(BLL 类)上使用 HttpContextAccessor,虽然我成功初始化了 ContextAccessor,但同时 HttpContext 本身为空。

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

UserPermissionConfig 组件代码

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

有什么帮助吗?

【问题讨论】:

  • IUserPermissionConfig 是如何注册的?您什么时候请求它的实例?
  • IHttpContextAccessor 仅在 asp.net core 请求范围内有效
  • builder.Services.AddSingleton<IUserPermissionConfig, UserPermisionConfig>();
  • 没有那么多好的曾经使用IHttpContextAccessor的原因(这是一个设计糟糕的服务和Microsoft admits as much)——为什么不改变SetUserPermissionsSession来添加一个ClaimsIdentity参数呢?
  • 我编辑了代码以便更好地理解

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


【解决方案1】:

我想你可以看看这个document

正如文档中提到的:

HttpContext 不是线程安全的。在处理请求之外读取或写入 HttpContext 的属性可能会导致 NullReferenceException。

在Asp.net中如果你在global.asax.cs的Application_Start()方法中直接调用httpcontext,你会得到类似的错误

如果您的代码在 Asp.net 中的 HttpModule 中,请查看此 document 以了解如何将模块代码迁移到中间件

我尝试如下:

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

注册服务:

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();

调用管道中的中间件:

.....

app.UseSession();

app.UseMiddleware<MyMiddleware>();
.....

在我的情况下效果很好:

【讨论】:

    【解决方案2】:

    好的,您似乎正在尝试直接从 Program.cs 访问 HTTP 上下文。这不是它的工作原理。

    HTTP 上下文仅在传入的 HTTP 请求期间可用。

    您的IUserPermissionConfig 服务必须从某处(控制器、过滤器、中间件)的 ASP.net 管道调用。

    【讨论】:

    • 在旧的 asp net mvc 中,可以从 global.asax.cs 调用 httpcontext ...无论如何谢谢
    猜你喜欢
    • 2017-07-26
    • 1970-01-01
    • 2021-05-05
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 2018-11-18
    相关资源
    最近更新 更多