我在各种 Controller 上使用 AuthorizeAttribute,这些 Controller 可能需要根据请求本身的某些属性返回 403 或 429(请求太多)。我完全在自定义 OnAuthorization 实现中实现了它,然后在必要时抛出一个带有适当响应代码的新 HttpResponseException。在我的机器上运行良好...
在大规模(每分钟数千个请求)下,此实现非常糟糕,以至于它导致网站崩溃。将相同的逻辑移动到 Controller 操作本身并仅返回适当的 HttpResponseMessage 就性能而言效果很好,因此在 OnAuthorization 中抛出异常的代价似乎是性能问题的根本原因。
我喜欢在一个属性中实现它的想法,我可以用它来装饰多个 Controller 和 Action ,我强烈不喜欢将即使是少量的逻辑移动到 Controller Action 中,然后重复多次。是否可以在不抛出异常的情况下从注释返回适当的 HTTP 状态?即使它不是从 AuthorizeAttribute 继承的,以这种方式装饰代码也是可取的。
编辑:这是 Web API 2,不是 MVC
最佳答案
正如您所发现的,抛出异常的代价很高。这种情况下的技巧是覆盖属性中的响应。由于 MVC 和 WebAPI 不同(至少在 MVC6 之前),因此有两种不同的方法。
MVC
设置AuthorizationContext.Result
允许您有效地覆盖正在执行的操作。设置这个值将阻止它所附加的操作运行:
public override void OnAuthorization(AuthorizationContext filterContext)
{
if(Throw403)
{
filterContext.Result = new HttpStatusCodeResult(403);
}
}
网络接口(interface)
非常相似,但您必须改为设置 HttpActionContext.Response
属性(property)。它的一个方便的功能是,您可以为 HTTP 状态代码获得一个很好的 enum
:
public override void OnAuthorization(HttpActionContext actionContext)
{
if(Throw403)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
关于c# - 您能否从 AuthorizeAttribute 返回 HTTP 响应而不抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39049604/