Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Implementing and registering a message handler in ASP.NET Web API 2
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;
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.
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