在构造函数中注入接口的 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>();
我的问题陈述与 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>();