Swagger调用Get接口触发NullReferenceException,Angular调用正常
问题根源分析
Swagger UI调用接口时触发NullReferenceException的核心原因是:Swagger请求未携带包含ClaimTypes.NameIdentifier的身份凭证,导致User.FindFirst(ClaimTypes.NameIdentifier)返回null,访问其Value属性时直接抛出空引用异常。而Angular客户端调用时会自动携带登录后的身份令牌(比如JWT),后台能正常获取到Claim值,所以接口运行正常。
解决步骤
1. 配置Swagger支持身份认证
让Swagger UI可以手动输入身份令牌,模拟客户端的认证请求:
builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "你的API名称", Version = "v1" }); // 定义JWT认证规则 var securityScheme = new OpenApiSecurityScheme { Name = "Authorization", Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "请输入格式为 `Bearer {JWT令牌}` 的认证信息", Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }; c.AddSecurityDefinition("Bearer", securityScheme); // 全局启用认证要求 var securityRequirement = new OpenApiSecurityRequirement { { securityScheme, Array.Empty<string>() } }; c.AddSecurityRequirement(securityRequirement); });
配置完成后,Swagger UI右上角会出现「Authorize」按钮,点击输入Bearer {你的JWT令牌},再调用接口就会携带认证头,后台能正常获取Claim值。
2. 代码层面增加空值防护
修改接口代码,提前判断Claim是否存在,避免未处理的异常:
[HttpGet] public async Task<IActionResult> GetOrders() { var marketingIdClaim = User.FindFirst(ClaimTypes.NameIdentifier); if (marketingIdClaim == null || !int.TryParse(marketingIdClaim.Value, out int marketingId)) { return Unauthorized("身份验证失败,无法获取用户ID"); } var orders = await _repo.GetMarketeerOrders(marketingId); var ordersToReturn = _mapper.Map<IEnumerable<MarketeerOrdersDto>>(orders); return Ok(ordersToReturn); }
这样即使没有合法的Claim,也会返回明确的401 Unauthorized错误,而非崩溃的空引用异常。
3. 确认客户端认证逻辑
Angular客户端能正常调用,说明其请求自动携带了认证头(大概率是通过HTTP拦截器注入JWT令牌)。可以检查客户端的拦截器代码,确保Swagger模拟的请求头和客户端一致。
内容的提问来源于stack exchange,提问作者Ahmed Gamal
相关产品推荐
相关产品推荐

