如何扼杀在Web API请求? [英] How to throttle requests in a Web Api?
问题描述
我想实现通过以下请求限制:
I'm trying to implement request throttling via the following:
<一个href="http://stackoverflow.com/questions/33969/best-way-to-implement-request-throttling-in-asp-net-mvc">Best方法来实现请求限制在ASP.NET MVC?
我已经拉了code到我的解决方案,并饰有属性的API控制器端点:
I've pulled that code into my solution and decorated an API controller endpoint with the attribute:
[Route("api/dothis/{id}")]
[AcceptVerbs("POST")]
[Throttle(Name = "TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
[Authorize]
public HttpResponseMessage DoThis(int id) {
这编译,但该属性的code不被击中,而节流不起作用。我没有得到任何错误,但。我在想什么?
This compiles but the attribute's code doesn't get hit, and the throttling doesn't work. I don't get any errors though. What am I missing?
推荐答案
您似乎是对的ASP.NET Web API控制器一个ASP.NET MVC控制器和动作过滤器混淆动作过滤器。这些是2完全不同的类别:
You seem to be confusing action filters for an ASP.NET MVC controller and action filters for an ASP.NET Web API controller. Those are 2 completely different classes:
- 对于ASP.NET MVC:<一href="http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute%28v=vs.118%29.aspx"><$c$c>System.Web.Mvc.ActionFilterAttribute$c$c> - >这就是你从链接 得到
- 有关的ASP.NET Web API:<一href="http://msdn.microsoft.com/en-us/library/system.web.http.filters.actionfilterattribute%28v=vs.118%29.aspx"><$c$c>System.Web.Http.Filters.ActionFilterAttribute$c$c> - >这就是你需要实现
看来,你已经证明了什么是Web API控制器动作(一个是控制器从 ApiController
导出内声明的)。所以,如果你想申请自定义过滤器的话,他们必须来自 System.Web.Http.Filters.ActionFilterAttribute
。
It appears that what you have shown is a Web API controller action (one that is declared inside a controller deriving from ApiController
). So if you want to apply custom filters to it, they must derive from System.Web.Http.Filters.ActionFilterAttribute
.
因此,让我们继续前进,适应$ C $下的Web API:
So let's go ahead and adapt the code for Web API:
public class ThrottleAttribute : ActionFilterAttribute
{
/// <summary>
/// A unique name for this Throttle.
/// </summary>
/// <remarks>
/// We'll be inserting a Cache record based on this name and client IP, e.g. "Name-192.168.0.1"
/// </remarks>
public string Name { get; set; }
/// <summary>
/// The number of seconds clients must wait before executing this decorated route again.
/// </summary>
public int Seconds { get; set; }
/// <summary>
/// A text message that will be sent to the client upon throttling. You can include the token {n} to
/// show this.Seconds in the message, e.g. "Wait {n} seconds before trying again".
/// </summary>
public string Message { get; set; }
public override void OnActionExecuting(HttpActionContext actionContext)
{
var key = string.Concat(Name, "-", GetClientIp(actionContext.Request));
var allowExecute = false;
if (HttpRuntime.Cache[key] == null)
{
HttpRuntime.Cache.Add(key,
true, // is this the smallest data we can have?
null, // no dependencies
DateTime.Now.AddSeconds(Seconds), // absolute expiration
Cache.NoSlidingExpiration,
CacheItemPriority.Low,
null); // no callback
allowExecute = true;
}
if (!allowExecute)
{
if (string.IsNullOrEmpty(Message))
{
Message = "You may only perform this action every {n} seconds.";
}
actionContext.Response = actionContext.Request.CreateResponse(
HttpStatusCode.Conflict,
Message.Replace("{n}", Seconds.ToString())
);
}
}
}
其中 GetClientIp
方法来自 这个帖子
。
where the GetClientIp
method comes from this post
.
现在,你可以在你的Web API控制器动作使用这个属性。
Now you can use this attribute on your Web API controller action.
这篇关于如何扼杀在Web API请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!