Промежуточное ПО и фильтры в минимальных API
Добавляйте аутентификацию, авторизацию, обработку исключений и фильтры конечных точек в конвейеры минимальных API.
«Промежуточное ПО и фильтры в минимальных API» — бесплатный урок C# Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Промежуточное ПО и фильтры конечных точек
ASP.NET Core имеет два уровня расширения: промежуточное ПО (оборачивает весь конвейер и выполняется для каждого запроса) и фильтры конечных точек (выполняются только для определённых конечных точек). Оба механизма работают в минимальных API.
Добавление промежуточного ПО в минимальные API
Стандартное промежуточное ПО ASP.NET Core добавляется с помощью методов app.Use*. Порядок важен: промежуточное ПО выполняется в том порядке, в котором оно зарегистрировано.
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.MapGet("/secure", () => "Protected endpoint")
.RequireAuthorization();
app.Run();Встроенные фильтры конечных точек
Фильтры конечных точек похожи на промежуточное ПО, ограниченное одной конечной точкой. Используйте AddEndpointFilter, чтобы добавить фильтр непосредственно в код. Фильтры могут досрочно завершить обработку, вернув результат без вызова next.
app.MapGet("/guarded", () => "Secret data")
.AddEndpointFilter(async (ctx, next) =>
{
var header = ctx.HttpContext.Request.Headers["X-Api-Key"];
if (header != "my-secret-key")
return Results.Unauthorized();
return await next(ctx); // proceed to handler
});Фильтры конечных точек на основе классов
Реализуйте IEndpointFilter, чтобы создавать повторно используемые фильтры. Их можно применять к отдельным конечным точкам или ко всей группе маршрутов.
public class LoggingFilter : IEndpointFilter
{
private readonly ILogger<LoggingFilter> _logger;
public LoggingFilter(ILogger<LoggingFilter> logger) => _logger = logger;
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext ctx,
EndpointFilterDelegate next)
{
_logger.LogInformation("Before: {Path}", ctx.HttpContext.Request.Path);
var result = await next(ctx);
_logger.LogInformation("After: {Path}", ctx.HttpContext.Request.Path);
return result;
}
}
// Apply to a group
app.MapGroup("/api").AddEndpointFilter<LoggingFilter>();Промежуточное ПО для обработки исключений
Используйте app.UseExceptionHandler или встроенное промежуточное ПО ProblemDetails, чтобы перехватывать необработанные исключения и возвращать ответы с описанием проблемы по RFC 7807.
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
// OR for custom logic:
app.UseExceptionHandler(errApp =>
errApp.Run(async ctx =>
{
var ex = ctx.Features.Get<IExceptionHandlerFeature>()?.Error;
ctx.Response.StatusCode = 500;
await ctx.Response.WriteAsJsonAsync(new { error = ex?.Message });
}));Промежуточное ПО с досрочным завершением
Используйте app.MapShortCircuit() (.NET 8+) или Results.StatusCode() в фильтре, чтобы немедленно вернуть ответ, не запуская весь конвейер.
// Block known bad bots at the edge
app.MapGet("/robots.txt", () => "User-agent: *\nDisallow: /")
.ShortCircuit(); // .NET 8: returns response immediately
// Or in a filter:
app.MapGet("/maintenance", () => "OK")
.AddEndpointFilter((ctx, next) =>
ValueTask.FromResult<object?>(Results.StatusCode(503)));Ограничение частоты запросов в .NET 7+
Встроенное промежуточное ПО для ограничения частоты запросов защищает конечные точки от злоупотреблений. Применяйте политики глобально или для отдельных конечных точек с помощью RequireRateLimiting().
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(opt =>
{
opt.AddFixedWindowLimiter("fixed", o =>
{
o.PermitLimit = 10;
o.Window = TimeSpan.FromSeconds(10);
o.QueueLimit = 0;
o.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
opt.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});
app.UseRateLimiter();
app.MapGet("/search", Search).RequireRateLimiting("fixed");Настройка CORS
Настройте политики CORS в службах и применяйте их глобально или для отдельных конечных точек, чтобы управлять источниками, которым разрешён доступ к вашему API.
builder.Services.AddCors(opt =>
opt.AddPolicy("AllowFrontend", policy =>
policy.WithOrigins("https://myapp.com")
.AllowAnyHeader()
.AllowAnyMethod()));
app.UseCors("AllowFrontend");
// Or per endpoint:
app.MapGet("/public-data", () => "data")
.RequireCors("AllowFrontend");Промежуточное ПО для кэширования ответов
AddOutputCache кэширует ответы на сервере. Применяйте его к отдельным конечным точкам, чтобы возвращать кэшированные ответы без обращения к базе данных при каждом запросе.
builder.Services.AddOutputCache();
app.UseOutputCache();
app.MapGet("/products", async (AppDbContext db) =>
Results.Ok(await db.Products.AsNoTracking().ToListAsync()))
.CacheOutput(p => p.Expire(TimeSpan.FromMinutes(5)));Порядок и объединение фильтров
Фильтры выполняются в порядке добавления: сначала внешние, затем внутренние — как промежуточное ПО. Можно объединить несколько фильтров для одной конечной точки или группы.
app.MapPost("/orders", CreateOrder)
.AddEndpointFilter<LoggingFilter>() // runs first
.AddEndpointFilter<ValidationFilter>() // runs second
.AddEndpointFilter<AuthFilter>() // runs third
.RequireAuthorization(); // JWT checked by middlewareПрактический пример: промежуточное ПО для ключа API
Повторно используемое промежуточное ПО для ключа API, которое считывает ключ из заголовка и немедленно возвращает 401, если ключ недействителен.
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly string _expectedKey;
public ApiKeyMiddleware(RequestDelegate next, IConfiguration cfg)
{
_next = next;
_expectedKey = cfg["ApiKey"] ?? throw new Exception("ApiKey not configured");
}
public async Task InvokeAsync(HttpContext ctx)
{
if (!ctx.Request.Headers.TryGetValue("X-Api-Key", out var key)
|| key != _expectedKey)
{
ctx.Response.StatusCode = 401;
await ctx.Response.WriteAsync("Invalid API key");
return;
}
await _next(ctx);
}
}
app.UseMiddleware<ApiKeyMiddleware>();Быстрая проверка
Каково ключевое различие между промежуточным ПО и фильтрами конечных точек в минимальных API?
Итоги: промежуточное ПО и фильтры
Основные выводы:
- Промежуточное ПО (UseX) выполняется глобально в порядке конвейера для каждого запроса
- Фильтры конечных точек (AddEndpointFilter) ограничены определёнными конечными точками или группами
- Реализуйте IEndpointFilter для создания повторно используемых классов фильтров, поддерживающих DI
- Встроенное промежуточное ПО: ограничение частоты запросов, CORS, кэширование ответов и обработка исключений
- Порядок фильтров важен: они вкладываются как промежуточное ПО (добавленный первым оказывается внешним)
Изучай C# с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 93
- Уроки
- 346
Часто задаваемые вопросы
Урок «Промежуточное ПО и фильтры в минимальных API» бесплатный?
Да — полный текст урока «Промежуточное ПО и фильтры в минимальных API» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Промежуточное ПО и фильтры в минимальных API»?
Добавляйте аутентификацию, авторизацию, обработку исключений и фильтры конечных точек в конвейеры минимальных API. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Промежуточное ПО и фильтры в минимальных API»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Создание первого минимального API
- Группы маршрутов, параметры и проверка
- Промежуточное ПО и фильтры в минимальных API
- OpenAPI, версионирование и развёртывание