.net core 无法解析自定义ValidationAttribute中的依赖项,ValidationConContext参数上的IServiceProvider设置为null

.net core 无法解析自定义ValidationAttribute中的依赖项,ValidationConContext参数上的IServiceProvider设置为null,.net-core,dependency-injection,autofac,asp.net-core-2.1,validationattribute,.net Core,Dependency Injection,Autofac,Asp.net Core 2.1,Validationattribute,一个ASP.NET Core 2.1 MVC应用程序,使用Autofac,遵循其关于安装()的文档 我正在尝试解决自定义ValidationAttribute中的依赖项。valicationContext.GetService返回的值始终返回null。检查私有成员serviceProvider的ValidationContext始终为空 我在设置中遗漏了什么,但这不起作用。依赖关系在应用程序的其他任何地方都可以解决,只是在ValidationAttribute中不能解决 public class

一个ASP.NET Core 2.1 MVC应用程序,使用Autofac,遵循其关于安装()的文档

我正在尝试解决自定义ValidationAttribute中的依赖项。valicationContext.GetService返回的值始终返回null。检查私有成员serviceProvider的ValidationContext始终为空

我在设置中遗漏了什么,但这不起作用。依赖关系在应用程序的其他任何地方都可以解决,只是在ValidationAttribute中不能解决

public class MyCustomAttribute : ValidationAttribute
{

    public MyCustomAttribute ()
    {

    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // THIS IS ALWAYS RETURNING NULL
        var IMyService service = (IMyService)validationContext.GetService(typeof(IMyService));

        return ValidationResult.Success;
    }
}

我不能说我以前尝试过这个,但在进行一些搜索时,我发现这似乎表明应该始终填充服务提供者(不是
ServiceContainer
属性,而是响应
GetService
调用的服务提供者)。诚然,这是从.NETCore早期的存档回购协议中获得的,但它应该仍然有效

查看一下,我发现private
serviceProvider
字段实际上是一个需要在某处实例化的函数;它实际上并不是对提供者的引用。这意味着如果它为null,则会发生以下两种情况之一:

  • 实例化
    ValidationContext
    的ASP.NET核心路径没有传入提供服务所需的
    IServiceProvider
  • 有东西坏了
  • 如果是#1,我想可能有多种原因。我会考虑像

    • 该属性正被运行在“ASP.NET管道”之外的东西使用——比如手动调用的验证,或者可能是在应用程序启动时没有请求的东西
    • 在完整管道无效的测试中使用该属性
    差不多吧。我并不是说这就是正在发生的事情,但我以前见过这样的问题,当它实际上是一个应用程序代码问题时,它似乎有些不正常。例如,有很多关于为什么“每个请求实例”依赖项不起作用的问题,结果是代码运行在没有请求的后台线程上,所以。。。是 啊我不知道你的应用程序是如何工作的,但那种“我正在做一些我忘记提及的事情,因为我认为这与我的应用程序无关”的东西在这里起了作用

    让我们假设你有一个超级普通的ASP.NET核心应用程序。基于我前面提到的问题和您发布的代码,这看起来应该是可行的,但事实并非如此。你不需要为这个做任何准备,它应该能工作。鉴于此。你可能发现了一些合法的不起作用的东西

    在执行此操作之前,您可能需要进行更多的调试。这可以帮你弄清楚到底发生了什么。我在那里链接的文章解释了如何设置它。这不是一个两步的过程,需要屏幕截图来帮助,否则我就把它放在这里

    在上面的失败语句上设置一个断点,然后切换到VisualStudio“调用堆栈”窗口。单击堆栈中较高的调用堆栈帧,查看实际创建该上下文对象的内容。只要轻轻一点,凭直觉,你可能就能找出问题所在。也许它会指向你的应用程序中你没有意识到你正在做的事情,也许它会指向ASP.NET核心中的一个bug。如果它是ASP.NET核心中的一个bug,那么拥有从调试会话中找到的信息将对该团队非常有帮助


    最后,如果我没有提到在像这样的属性中手动解析服务在技术上是服务位置,而不是依赖项注入,那么我将是失职的。如果您完全避免,这将是一个更好的全面解决方案。尽管Autofac的原理也适用,但我们将介绍如何使用简单的喷油器解决此问题。设置模型验证器并使用模型验证器提供程序而不是属性可能是一种更好、更易测试的方法。这个问题的答案对此有更多的解释。

    我不能说我以前尝试过这个,但在进行一些搜索时,我发现这似乎表明服务提供者(不是
    ServiceContainer
    属性,而是将响应
    GetService
    调用的服务提供者)应该始终被填充。诚然,这是从.NETCore早期的存档回购协议中获得的,但它应该仍然有效

    查看一下,我发现private
    serviceProvider
    字段实际上是一个需要在某处实例化的函数;它实际上并不是对提供者的引用。这意味着如果它为null,则会发生以下两种情况之一:

  • 实例化
    ValidationContext
    的ASP.NET核心路径没有传入提供服务所需的
    IServiceProvider
  • 有东西坏了
  • 如果是#1,我想可能有多种原因。我会考虑像

    • 该属性正被运行在“ASP.NET管道”之外的东西使用——比如手动调用的验证,或者可能是在应用程序启动时没有请求的东西
    • 在完整管道无效的测试中使用该属性
    差不多吧。我并不是说这就是正在发生的事情,但我以前见过这样的问题,当它实际上是一个应用程序代码问题时,它似乎有些不正常。例如,有很多关于为什么“每个请求实例”依赖项不起作用的问题,结果是代码运行在没有请求的后台线程上,所以。。。是 啊我不知道你的应用程序是如何工作的,但那种“我正在做一些我忘记提及的事情,因为我认为这与我的应用程序无关”的东西在这里起了作用

    假设您有一个超级普通的ASP.NET核心应用程序