ASP.NET Core:主控制器调用其他控制器时TryValidateModel抛NullReferenceException
问题解决思路
原因分析
- TryValidateModel抛空引用:从MainController调用其他控制器方法时,被调用控制器的
ControllerContext(包含HttpContext、ModelState等核心上下文对象)未被正确初始化,TryValidateModel内部依赖这些对象完成验证,因此抛出NullReferenceException。而直接请求控制器时,ASP.NET Core框架会自动完成上下文初始化,所以运行正常。 - Validator.TryValidateObject拿不到DbContext:手动创建的
ValidationContext默认未关联ASP.NET Core的依赖注入容器,因此validationContext.GetService(typeof(SvrContext))无法获取到已注入的DbContext实例。
解决方案
方案1:初始化被调用控制器的上下文(适配TryValidateModel)
如果想继续使用TryValidateModel,在调用目标控制器方法前,将MainController的上下文赋值给目标控制器:
else if (strEntityIdentifier == "VGBKKA2") { // 复制当前控制器上下文到目标控制器 _valveControlsController.ControllerContext = this.ControllerContext; var JSONresult = await _valveControlsController.Put(key, values); }
目标控制器将拥有完整的上下文环境,TryValidateModel可正常执行,自定义验证属性也能通过上下文获取DbContext。
方案2:给ValidationContext传入服务提供器(适配Validator.TryValidateObject)
如果倾向于使用Validator.TryValidateObject,创建ValidationContext时传入当前请求的服务提供器:
var validationResultList = new List<ValidationResult>(); // 传入HttpContext的服务提供器,关联DI容器 var validationContext = new ValidationContext(model, serviceProvider: HttpContext.RequestServices); bool bValidate = Validator.TryValidateObject(model, validationContext, validationResultList, true);
此时自定义验证属性中的validationContext.GetService(typeof(SvrContext))就能正确获取到DbContext实例。
内容的提问来源于stack exchange,提问作者ManCon25
相关产品推荐
相关产品推荐

