Last active
June 13, 2021 18:02
-
-
Save jessebarocio/5a33486c556e4cfb8b3d0942d4ae5917 to your computer and use it in GitHub Desktop.
Implementing and registering a message handler in ASP.NET Web API 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Net; | |
using System.Net.Http; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace MyApi.Infrastructure | |
{ | |
public class RateLimitingHandler : DelegatingHandler | |
{ | |
private const string RateLimitHeaderName = "X-MyApi-Rate-Limit-Remaining"; | |
// The service that handles tracking rate limits for API consumers. | |
RateLimitingService _service = new RateLimitingService(); | |
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | |
{ | |
HttpResponseMessage response; | |
// Get the token that is making this request. | |
string consumerToken = request.Headers.Authorization.Parameter; | |
// Get the number of calls that this token is authorized to make. | |
int remainingCalls = _service.GetRemainingCalls(consumerToken); | |
// If the number of calls < 1 then the consumer has hit their rate limit. | |
// Return an appropriate response. | |
if(remainingCalls < 1) | |
{ | |
response = request.CreateResponse( | |
(HttpStatusCode)429, new { Message = "Rate limit exceeded!" }); | |
} | |
else // Otherwise return the response from the controller. | |
{ | |
response = await base.SendAsync(request, cancellationToken); | |
// Append a custom header so the API consumer can see the remaining request limit. | |
response.Headers.Add(RateLimitHeaderName, (--remainingCalls).ToString()); | |
} | |
return response; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using MyApi.Infrastructure; | |
using System.Web.Http; | |
namespace MyApi | |
{ | |
public static class WebApiConfig | |
{ | |
public static void Register(HttpConfiguration config) | |
{ | |
... | |
// Register as a global handler - all Web API requests will go through | |
// RateLimitingHandler. | |
config.MessageHandlers.Add(new RateLimitingHandler()); | |
// -- OR -- | |
// Register the handler for a specific route - only Web API requests | |
// that match this route will go through RateLimitingHandler. | |
config.Routes.MapHttpRoute( | |
name: "TasksApi", | |
routeTemplate: "api/Tasks/{id}", | |
defaults: new { id = RouteParameter.Optional }, | |
constraints: null, | |
handler: new RateLimitingHandler() | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment