在构造函数中注入接口的 WebApi 自定义过滤器不会被调用

WebApi Custom Filter with injected interface in constructor does not get called

我的问题陈述与 this question 相同,即在 attribute/filter 中使用注入服务。我已经尝试了 B Z 给出的解决方案,下面是我的代码,与给出的解决方案一致。

//marker attribute
public class AuthorizeViewAttribute : Attribute { }

//filter
public class AuthorizeViewFilter : IAuthorizationFilter
{
    private readonly IAccessRightsService _iAccessRightService;
    public AuthorizeViewFilter(IAccessRightsService iAccessRightService)
    {
        _iAccessRightService = iAccessRightService;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        RoleFeature roleFeature = _iAccessRightService.GetRoleFeatures();

        if (roleFeature.IsView)
        {
            //redirect to controller
        }
    }      
}

以下是我使用的 ninject 绑定:

this.BindFilter<AuthorizeViewFilter>(System.Web.Mvc.FilterScope.Controller, 0)
        .WhenControllerHas<AuthorizeViewAttribute>();

我不需要属性中的任何参数,所以我想我不需要使用 this answer

中提到的 WithConstructorArgument

但我的过滤器从未被调用。我在 AuthorizeViewAttribute 中放了一个默认构造函数,调试发现控件跳转到 AuthorizeViewAttribute 中的默认构造函数,继续控制器方法

我找不到任何解决办法。有什么建议吗?

简短的故事:您似乎正在尝试在 webapi 控制器上使用 MVC 过滤器和 MVC 绑定。这就是它不起作用的原因。

长话短说:首先创建一个 webapi 过滤器提供程序(注意,您需要 Ninject.Extensions.Factories 包才能让 Func<AuthorizeViewFilter> 由 Ninject 解析)

public class AuthorizeViewFilterProvider : System.Web.Http.Filters.IFilterProvider
{
    private readonly Func<AuthorizeViewFilter> _authorizeViewFilterFactory;

    public AuthorizeViewFilterProvider(Func<AuthorizeViewFilter> authorizeViewFilterFactory)
    {
        this._authorizeViewFilterFactory = authorizeViewFilterFactory;
    }

    public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
        if(!actionDescriptor.GetCustomAttributes<AuthorizeViewAttribute>().Any())
            return Enumerable.Empty<FilterInfo>();

        return new[]
        {
            new FilterInfo(this._authorizeViewFilterFactory(), FilterScope.Action)
        };
    }
}

然后创建一个 webapi 过滤器

public class AuthorizeViewFilter : System.Web.Http.Filters.IAuthorizationFilter
{
    private readonly IAccessRightsService _iAccessRightService;
    public AuthorizeViewFilter(IAccessRightsService iAccessRightService)
    {
        _iAccessRightService = iAccessRightService;
    }

    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        RoleFeature roleFeature = _iAccessRightService.GetRoleFeatures();

        if (roleFeature.IsView)
        {
            return continuation();
        }
        else
          return Task.FromResult(actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Access denied"));
    }
}

然后,在您的绑定设置中绑定 FilterProvider :

this.Bind<System.Web.Http.Filters.IFilterProvider>().To<AuthorizeViewFilterProvider>();