【问题标题】:Throttle ASP.NET Web Api with ActionFilterAttribute extension使用 ActionFilterAttribute 扩展节流 ASP.NET Web Api
【发布时间】:2018-06-12 14:35:22
【问题描述】:

我正在尝试向我的 Web Api 应用程序添加使用限制。但是,自定义属性没有被实现。

自定义属性

using System;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc;

namespace MyApp.Filters
{
    public enum TimeUnit
    {
        Minute = 60,
        Hour = 3600,
        Day = 86400
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class ThrottleAttribute : ActionFilterAttribute
    {
        public TimeUnit TimeUnit { get; set; }
        public int Count { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ...
        }
    }
}

控制器

namespace MyApp.Controllers
{
    public class GetUsersController : ApiController
    {
        [Throttle(TimeUnit = TimeUnit.Minute, Count = 5)]
        [Throttle(TimeUnit = TimeUnit.Hour, Count = 20)]
        [Throttle(TimeUnit = TimeUnit.Day, Count = 100)]
        public ICollection<Users> Get(int id)
        {
            ...
        }
    }
}

我走了吗?错误地实现属性?扩展错误的属性?我知道我使用的是System.Web.Mvc 而不是System.Web.Http.Filters...但是我所看到的所有资源都要求这样做。也许你有更好的答案? :)

【问题讨论】:

  • 出于好奇 - 你为什么要这样做?你有什么要求?因为如果它与正在使用的系统资源有关 - 在管道的早期就有更有效的节流方法。与其他选项相比,操作过滤器相对“晚”。
  • 老实说,因为这是我发现其他人所做的。如果您有更好的方法来实现节流,请告诉我。此外,这个应用程序很旧,.NET 框架 4.5 和 WebApi 4.0 - 所以我尝试使用几个 nuget 包进行节流,但它试图为更高版本的 WebApi 更新整个应用程序并抛出其他所有内容。跨度>
  • 这很公平,但我的意思是你为什么要这样做?为什么你首先要节流?您是在节流以控制消费者对您服务的使用,还是更多地保护您的系统资源免受过度工作的影响?
  • 我的经理担心人们会编写循环并尝试不断地向 API 发送请求(可能会使服务器陷入困境等等)。我的印象是(除非最终用户真的是混蛋),它将是单线程的,所以这不应该成为问题。但这是经理们想要的。
  • 请在您的覆盖函数中发布代码。也许您忘记拨打base.OnActionExecuting(filterContext)

标签: c# asp.net asp.net-mvc asp.net-web-api


【解决方案1】:

确保您在代码中的某个位置调用base.OnActionExecuting(filterContext)。如果您使用的是 .NET Standard(不了解 Core),那么您还应该记得在 App_Start\FilterConfig.cs 中注册您的过滤器:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    //add this part
    filters.Add(new ThrottleAttribute());
}

【讨论】:

    【解决方案2】:

    问题是因为您使用的是来自System.Web.MvcActionFilterAttribute,而不是来自System.Web.Http.Filters,正如您在问题中提到的那样。

    MVC 过滤器将仅作为 MVC 生命周期的一部分为控制器执行。 API 控制器的 HTTP 过滤器也是如此。这意味着您的属性应该如下所示:

    using System.Web.Http.Controllers;
    using System.Web.Http.Filters;
    
    public class ThrottleAttribute : ActionFilterAttribute
    {
        // Note the different signature to what you have in your question.
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            //
        }
    }
    

    如果您现在在该方法上放置一个断点,并调用您的 API 控制器,它应该会命中它。

    如果您想将现有的过滤器用于 MVC 控制器,那将可以正常工作。

    【讨论】:

      猜你喜欢
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2023-03-17
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 2019-10-30
      相关资源
      最近更新 更多