.NET Core跨控制器调用时ClaimsPrincipal为空的修复方案咨询
问题原因
在.NET Core中,手动实例化的控制器不会被依赖注入容器初始化,因此ControllerContext、User等属性默认是null。而.NET Framework的旧机制中,控制器上下文会自动传递,所以跨控制器调用能正常获取Identity。
无需大量修改的修复方案
方案1:手动传递ControllerContext(改动最小)
在跨控制器调用时,把当前控制器的ControllerContext赋值给新实例化的控制器,这样新控制器就能继承当前的HttpContext和User信息,无需修改基类或其他控制器。
修改FirstController的Put方法:
[HttpPut] [HttpPost] [Route("/api/firstcontroller")] public IActionResult Put([FromBody] MyDTO data) { var token = Identity.Token; // 取值正常 var secondController = new SecondController(ContextFactory); // 关键:传递当前控制器的上下文 secondController.ControllerContext = this.ControllerContext; secondController.internalPut(something); // 不再触发NullReferenceException return Ok(); }
适用场景:跨控制器调用的次数较少,不想改动基类代码。
方案2:修改基类用属性注入IHttpContextAccessor(一劳永逸)
通过给BaseApiController添加属性注入的IHttpContextAccessor,兼容DI创建和手动实例化的控制器,无需修改100多个控制器的构造函数。
步骤1:注册IHttpContextAccessor服务
在Program.cs(或Startup.cs)的服务注册代码中添加:
builder.Services.AddHttpContextAccessor();
步骤2:修改BaseApiController
[ApiController] [Route("/api/[controller]")] [Route("/api/[controller]/[action]")] public class BaseApiController : ControllerBase { protected readonly IMyContextFactory ContextFactory; // 属性注入,无需修改子类构造函数 [FromServices] public IHttpContextAccessor HttpContextAccessor { get; set; } public BaseApiController(IMyContextFactory contextFactory) { ContextFactory = contextFactory; } public TokenIdentity Identity { get { // 优先从HttpContextAccessor获取上下文,兼容手动实例化的场景 var currentUser = HttpContextAccessor?.HttpContext?.User ?? User; return currentUser?.Identity as TokenIdentity; } } }
适用场景:跨控制器调用频繁,希望一次性解决所有类似问题,无需每次调用都写传递代码。
内容的提问来源于stack exchange,提问作者Saibamen
相关产品推荐
相关产品推荐

