You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core认证中匿名用户DI注入User类如何返回null?

ASP.NET Core 7中匿名请求时注入null到<User?>参数

场景与问题

在.NET 7的ASP.NET Core项目中,有一个同时允许认证用户和匿名用户访问的端点,需要根据用户认证状态执行不同逻辑。其他面向认证用户的服务中注入了作用域自定义类User,希望匿名场景下该类解析为null。

原实现代码:

// 生产环境中,非匿名用户会从数据库查询用户信息
builder.Services.AddScoped<User>(services => {
    if (User.IsAuthenticated())
        return new User(/* ... */);
    else return null;
});

// 端点注册
app.MapGet("/echo", (User? authedUser) => authedUser == null ? "Anonymous" : "Authed").RequireAuthorization().AllowAnonymous();

遇到的问题:DI工厂返回null符合预期,但匿名请求时DI抛出异常,提示未注册User实例——因为默认DI容器不允许注册的服务返回null。

解决方案

1. 注册IHttpContextAccessor获取请求上下文

要在DI工厂中判断用户认证状态,需先注册IHttpContextAccessor来访问当前请求的上下文信息:

builder.Services.AddHttpContextAccessor();

2. 注册可空类型User?而非User

将服务注册为可空引用类型,让DI容器允许返回null值:

builder.Services.AddScoped<User?>(services => {
    var httpContextAccessor = services.GetRequiredService<IHttpContextAccessor>();
    var httpContext = httpContextAccessor.HttpContext;
    
    // 验证用户是否已认证
    if (httpContext?.User?.Identity?.IsAuthenticated == true)
    {
        // 生产环境从数据库查询并返回用户实例
        return new User(/* 填充用户信息 */);
    }
    
    // 匿名用户返回null
    return null;
});

3. 调整端点参数与授权配置

端点参数保持User? authedUser,同时简化授权配置(AllowAnonymous已足够允许匿名访问,无需额外RequireAuthorization,除非有特定策略需求):

app.MapGet("/echo", (User? authedUser) => 
    authedUser == null ? "Anonymous" : "Authed")
    .AllowAnonymous();

原理说明

ASP.NET Core DI容器默认要求注册的服务必须返回非null实例,除非注册的是可空引用类型(如User?)。当端点参数声明为User?时,DI会调用GetService<User?>而非GetRequiredService<User>,此时工厂返回null时容器会正常处理,不会抛出异常。

内容的提问来源于stack exchange,提问作者Dynalon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:12:44