Sprache: C#
Dieses Snippet beantwortet die häufige Frage „Wie verhindere ich zu viele Requests auf meine .NET API?“.
Es zeigt, wie man [b]Requests pro Client serverseitig begrenzt[/b] – direkt in .NET 8 Minimal APIs, ohne Reverse Proxy oder API-Gateway.
[b]Was passiert nach Überschreiten des Limits?[/b]
Sobald ein Client mehr als 5 Requests innerhalb von 10 Sekunden sendet, werden weitere Anfragen sofort abgelehnt.
Die API antwortet automatisch mit H[b]TTP 429 (Too Many Requests)[/b]. Da QueueLimit = 0 gesetzt ist, werden Anfragen nicht gepuffert, sondern konsequent verworfen – ideal für klare Schutzmechanismen und vorhersagbares Verhalten.
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("per-client", limiter =>
{
limiter.Window = TimeSpan.FromSeconds(10);
limiter.PermitLimit = 5;
limiter.QueueLimit = 0;
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/api/data", () => Results.Ok("Zugriff erlaubt"))
.RequireRateLimiting("per-client");
app.Run();
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("per-client", limiter =>
{
limiter.Window = TimeSpan.FromSeconds(10);
limiter.PermitLimit = 5;
limiter.QueueLimit = 0;
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/api/data", () => Results.Ok("Zugriff erlaubt"))
.RequireRateLimiting("per-client");
app.Run();
Alte URL:
/snippet/zu-viele-api-aufrufe-so-begrenzt-du-requests-pro-client-in-net8/16225
[b]Du verwendest noch kein .NET 8?[/b]
So kannst du es in älteren .NET-Versionen (z. B. .NET 6/7) umsetzen – mit einem einfachen In-Memory Middleware-Ansatz (ohne externe Pakete):
Code (ASP.NET Core 6/7)
[code]using System.Collections.Concurrent;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var requests = new ConcurrentDictionary();
var window = TimeSpan.FromSeconds(10);
var limit = 5;
app.Use(async (context, next) =>
{
var key = context.Connection.RemoteIpAddress?.ToString() ?? „unknown“;
var now = DateTime.UtcNow;
var entry = requests.GetOrAdd(key, _ => (0, now));
if (now – entry.WindowStart > window)
entry = (0, now);
if (entry.Count >= limit)
{
context.Response.StatusCode = StatusCodes.Status429TooManyRequests;
return;
}
requests[key] = (entry.Count + 1, entry.WindowStart);
await next();
});
app.MapGet(„/api/data“, () => Results.Ok(„Zugriff erlaubt“));
app.Run();
[/code]
Auch hier gilt: Nach Überschreiten des Limits wird HTTP 429 zurückgegeben.
Für produktive Szenarien (Cluster, Redis, Sliding Window) empfiehlt sich später ein dediziertes Rate-Limiting-Framework.
[b]Für noch ältere .NET-Versionen: ASP.NET Web API 2 / .NET Framework 4.x[/b]
So kannst du es in noch älteren .NET-Versionen (ASP.NET Web API / MVC auf .NET Framework) umsetzen:
Code (ASP.NET Web API 2 / .NET Framework 4.x)
[code]using System;
using System.Collections.Concurrent;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class RateLimitAttribute : ActionFilterAttribute Requests();
{
private static readonly ConcurrentDictionary
= new ConcurrentDictionary
public int PermitLimit { get; set; } = 5;
public int WindowSeconds { get; set; } = 10;
public override void OnActionExecuting(HttpActionContext actionContext)
{
var key = GetClientKey(actionContext);
var now = DateTime.UtcNow;
var window = TimeSpan.FromSeconds(WindowSeconds);
var entry = Requests.GetOrAdd(key, _ => (0, now));
if (now – entry.WindowStart > window)
entry = (0, now);
if (entry.Count >= PermitLimit)
{
actionContext.Response = actionContext.Request.CreateResponse(
(HttpStatusCode)429, „Too Many Requests“);
return;
}
Requests[key] = (entry.Count + 1, entry.WindowStart);
base.OnActionExecuting(actionContext);
}
private static string GetClientKey(HttpActionContext ctx)
{
// simpel: IP-Adresse; je nach Hosting/Proxy ggf. X-Forwarded-For auswerten
var ip = ctx.Request.GetOwinContext()?.Request?.RemoteIpAddress;
return string.IsNullOrWhiteSpace(ip) ? „unknown“ : ip;
}
}
[/code]
[b]Anwendung (Web API Controller)[/b]
[code]using System.Web.Http;
public class DataController : ApiController
{
[RateLimit(PermitLimit = 5, WindowSeconds = 10)]
[HttpGet]
public IHttpActionResult Get()
{
return Ok(„Zugriff erlaubt“);
}
}
[/code]