【问题标题】:A suitable constructor could not be found for type filter找不到适合类型过滤器的构造函数
【发布时间】:2018-10-18 11:04:03
【问题描述】:

我有这个最近创建的类型过滤器,它位于一个单独的项目中。

public class RolesFilterAttribute : TypeFilterAttribute
{
    public RolesFilterAttribute() : base(typeof(RolesFilterAttributeImpl))
    {

    }

    public class RolesFilterAttributeImpl : IActionFilter
    {
        private readonly ValidateRoleClient validateRoleClient;
        private string Role;
        private string SecretKey;
        public RolesFilterAttributeImpl(string Role, string SecretKey, ValidateRoleClient validateRoleClient)
        {
            this.validateRoleClient = validateRoleClient;
            this.Role = Role;
            this.SecretKey = SecretKey;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.HttpContext.Request.Cookies["Token"] != null || context.HttpContext.Request.Cookies["RefreshToken"] != null)
            {
                TokenViewModel tvm = new TokenViewModel
                {
                    Token = context.HttpContext.Request.Cookies["Token"],
                    RefreshToken = context.HttpContext.Request.Cookies["RefreshToken"]
                };
                ValidateRoleViewModel vrvm = new ValidateRoleViewModel
                {
                    Role = Role,
                    SecretKey = SecretKey,
                    Token = tvm
                };
                validateRoleClient.ValidateRole(vrvm);
            }
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            throw new NotImplementedException();
        }
    }
}

这就是我在方法上方声明它的方式:

[TypeFilter(typeof(RolesFilterAttribute), Arguments = new object[] { "role", "abc1234" })]
public IActionResult About()
{
    return View();
}

我相信我已经在 Startup.cs 中声明了我需要的内容

services.AddScoped<ValidateRoleClient>();
services.AddScoped<RolesFilterAttribute>();

但是,当我启动应用程序并导航到 about 页面时,我遇到了这样的情况:

处理请求时发生未处理的异常。 InvalidOperationException:适合类型的构造函数 找不到“App.Link.Filters.RolesFilterAttribute”。确保 类型是具体的,并且为所有参数注册了服务 公共构造函数。 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(类型 instanceType, Type[] argumentTypes, out ConstructorInfo 匹配构造器,出 Nullable[] parameterMap)

还有什么我没有声明的遗漏?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.1


    【解决方案1】:
    [TypeFilter(typeof(RolesFilterAttribute), …]
    

    这表示您要创建的过滤器类型是RolesFilterAttribute。在类型过滤器中,您还传递了两个参数"role""abc1234"。因此,当类型过滤器将触发 RolesFilterAttribute 的创建时,它将寻找一个接受这两个字符串的构造函数。但是只有一个构造函数:

    public RolesFilterAttribute()
        : base(typeof(RolesFilterAttributeImpl))
    { }
    

    因此,无参数构造函数有两个参数。这就是您收到错误的原因。

    相反,您要做的是让[TypeFilter] 属性创建一个实际的过滤器。所以你需要在那里传递RolesFilterAttributeImpl 类型:

    [TypeFilter(typeof(RolesFilterAttributeImpl), Arguments = new object[] { "role", "abc1234" })]
    

    此时,您的RolesFilterAttribute 也变得多余,因此您可以摆脱它并定义RolesFilterAttributeImpl(我将其重命名为RolesFilter,因为它是一个过滤器,而不是一个属性或一个属性实现)。

    此外,由于您使用的是[TypeFilter],您确实不需要需要将您的过滤器类型注册到您的依赖注入容器中。您只需要注册您的类型的依赖项,因此在您的情况下只需 ValidateRoleClient

    所以你的过滤器实现看起来像这样:

    public class RolesFilter : IActionFilter
    {
        private readonly ValidateRoleClient validateRoleClient;
        private readonly string role;
        private readonly string secretKey;
    
        public RolesFilter(string role, string secretKey, ValidateRoleClient validateRoleClient)
        {
            this.validateRoleClient = validateRoleClient;
            this.role = role;
            this.secretKey = secretKey;
        }
    
        public void OnActionExecuted(ActionExecutedContext context)
        {
            // …
        }
    
        public void OnActionExecuting(ActionExecutingContext context)
        { }
    }
    

    [TypeFilter] 是顺便说一句。只是允许使用属性指定过滤器的一种方法。您还可以创建自己的属性,该属性实际上只是一个过滤器工厂,它负责在运行时创建过滤器实例。这就是 [TypeFilter] 默认为您所做的。

    另见我的related answer on the topic of using dependencies in MVC filters

    【讨论】:

      猜你喜欢
      • 2020-10-01
      • 2019-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多