Rob*_*ous 41 .net c# throttling asp.net-web-api
我正在尝试通过以下方式实现请求限制:
我已将该代码提取到我的解决方案中,并使用以下属性修饰了API控制器端点:
[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) {...}
Run Code Online (Sandbox Code Playgroud)
这会编译,但属性的代码不会被命中,并且限制不起作用.我没有收到任何错误.我错过了什么?
len*_*345 48
建议的解决方案不准确.至少有5个理由.
在实施限制时,还有许多问题和隐藏的障碍需要解决.有免费的开源选项.我建议您查看https://throttlewebapi.codeplex.com/.
Dar*_*rov 44
您似乎混淆了ASP.NET MVC控制器的动作过滤器和ASP.NET Web API控制器的动作过滤器.这是两个完全不同的类:
System.Web.Mvc.ActionFilterAttribute
- >这就是你从链接中得到的System.Web.Http.Filters.ActionFilterAttribute
- >这就是您需要实现的看来,您所显示的是Web API控制器操作(在控制器内部声明的操作ApiController
).因此,如果您要对其应用自定义过滤器,则必须从中派生System.Web.Http.Filters.ActionFilterAttribute
.
那么让我们继续并调整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())
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
其中GetClientIp
方法来自this post
.
现在,您可以在Web API控制器操作上使用此属性.
Kor*_*yem 32
WebApiThrottle现在已成为该领域的冠军.
它非常容易集成.只需将以下内容添加到App_Start\WebApiConfig.cs
:
config.MessageHandlers.Add(new ThrottlingHandler()
{
// Generic rate limit applied to ALL APIs
Policy = new ThrottlePolicy(perSecond: 1, perMinute: 20, perHour: 200)
{
IpThrottling = true,
ClientThrottling = true,
EndpointThrottling = true,
EndpointRules = new Dictionary<string, RateLimits>
{
//Fine tune throttling per specific API here
{ "api/search", new RateLimits { PerSecond = 10, PerMinute = 100, PerHour = 1000 } }
}
},
Repository = new CacheRepository()
});
Run Code Online (Sandbox Code Playgroud)
它也可以作为一个同名的nuget使用.
仔细检查using
操作过滤器中的语句。当您使用 API 控制器时,请确保您引用的是 ActionFilterAttribute ,System.Web.Http.Filters
而不是System.Web.Mvc
.
using System.Web.Http.Filters;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
40165 次 |
最近记录: |