如何限制 Web Api 中的请求? [英] How to throttle requests in a Web Api?

查看:33
本文介绍了如何限制 Web Api 中的请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过以下方式实现请求限制:

I'm trying to implement request throttling via the following:

在 ASP 中实现请求节流的最佳方式.NET MVC?

我已将该代码提取到我的解决方案中,并使用以下属性装饰了一个 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) {...}

这可以编译但属性的代码没有被命中,并且节流不起作用.不过我没有收到任何错误.我错过了什么?

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 MVC 控制器的动作过滤器和 ASP.NET Web API 控制器的动作过滤器.这是两个完全不同的类:

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:

您所展示的似乎是一个 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.

那么让我们继续修改 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 方法来自这篇文章.

现在您可以在 Web API 控制器操作上使用此属性.

Now you can use this attribute on your Web API controller action.

这篇关于如何限制 Web Api 中的请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆