我已经按照本教程,通过方法属性将依赖项注入自定义过滤器。
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=98
一切看起来都在工作,它命中过滤器并调用OnActionExecuting()方法。
我遇到的问题是,当用户未经过身份验证时,我想通过context.Response返回自定义响应,但它只是继续进入操作结果,如果过滤器不在那里。
以下是从上述网址获取的各种代码,以及我的自定义过滤器。
[Route("api/user/create")]
[AuthoriseRequest("Can_Create_User")]
[System.Web.Http.HttpPost]
public class AuthoriseRequest : Attribute
{
public string PermissionName { get; set; }
public AuthoriseRequest(string permissionName)
{
PermissionName = permissionName;
}
}
public class AuthoriseRequestActionFilter : IActionFilter<AuthoriseRequest>
{ ... }
public void OnActionExecuting(AuthoriseRequest request, HttpActionContext context)
{
var createUserRequest = (CreateUserRequest)context.ActionArguments["createUserRequest"];
var validator = _requestValidator.Validate(createUserRequest);
if (validator.IsValid())
{
var isAuthenticated =
_authenticationManager.AuthenticateRequest(...);
if (!isAuthenticated)
{
//THIS DOESN'T SET THE RESPONSE
var unauthorisedRequestResponse = new APIResponse<string>(null, false, validator.ToString());
context.Response = context.Request.CreateResponse(
HttpStatusCode.OK,
unauthorisedRequestResponse);
}
}
}
public sealed class ActionFilterDispatcher : IActionFilter
{
private readonly Func<Type, IEnumerable> container;
public ActionFilterDispatcher(Func<Type, IEnumerable> container)
{
this.container = container;
}
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext context,
CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
var descriptor = context.ActionDescriptor;
var attributes = descriptor.ControllerDescriptor.GetCustomAttributes<Attribute>(true)
.Concat(descriptor.GetCustomAttributes<Attribute>(true));
foreach (var attribute in attributes)
{
Type filterType = typeof(IActionFilter<>).MakeGenericType(attribute.GetType());
IEnumerable filters = this.container.Invoke(filterType);
foreach (dynamic actionFilter in filters)
{
actionFilter.OnActionExecuting((dynamic)attribute, context);
}
}
return continuation();
}
public bool AllowMultiple { get { return true; } }
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters, Container container)
{
GlobalConfiguration.Configuration.Filters.Add(new ActionFilterDispatcher(container.GetAllInstances));
container.RegisterCollection(typeof(IActionFilter<>), typeof(IActionFilter<>).Assembly);
filters.Add(new HandleErrorAttribute());
}
感谢。