简体   繁体   中英

Throttle ASP.NET Web Api with ActionFilterAttribute extension

I am attempting to add a usage throttle to my Web Api application. However, the custom attribute is not being implemented.

Custom Attribute

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)
        {
            ...
        }
    }
}

Controller

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)
        {
            ...
        }
    }
}

Am I way off? Implementing the attribute incorrectly? Extending the wrong attribute? I know that I'm using System.Web.Mvc instead of System.Web.Http.Filters ... but all of the resources I've seen have called for exactly that. Maybe you have a better answer? :)

Make sure you are calling base.OnActionExecuting(filterContext) at some point in your code. If you are using .NET Standard (don't know about Core) then you should also remember to register your filter in App_Start\\FilterConfig.cs:

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

The problem is because you're using ActionFilterAttribute from System.Web.Mvc , instead of from System.Web.Http.Filters , as you've mentioned in your question.

MVC filters will only be executed for a controller as part of the MVC lifecycle. The same goes for HTTP filters for API controllers. That means your attribute should look like this instead:

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)
    {
        //
    }
}

If you now put a breakpoint on that method, and make a call to your API controller, it should hit it.

If you want to use your existing filter for an MVC controller, that will work just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM