Общие сведения о ПО промежуточного слоя

Завершено

Целью веб-приложения является получение и реагирование на HTTP-запросы. Получается запрос, а затем сервер создает соответствующий ответ. Все в ASP.NET Core связано с этим циклом запроса и ответа.

Когда приложение ASP.NET Core получает HTTP-запрос, он проходит через ряд компонентов для создания ответа. Эти компоненты называются ПО промежуточного слоя. ПО промежуточного слоя можно рассматривать как конвейер, через который выполняется запрос, и каждый слой ПО промежуточного слоя может запускать код до и после следующего слоя в конвейере.

Схема, изображающая HTTP-запрос, так как это несколько ПО промежуточного слоя.

ПО промежуточного слоя и делегаты

ПО промежуточного HttpContext слоя реализуется в качестве делегата, который принимает объект и возвращает объект Task. Объект HttpContext представляет текущий запрос и ответ. Делегат — это функция, обрабатывающая запрос и ответ.

Рассмотрим следующий пример кода:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

В предыдущем коде:

  • WebApplication.CreateBuilder(args) создает новый WebApplicationBuilder объект.
  • builder.Build() создает новый WebApplication объект.
  • Первый app.Run() определяет делегат, который принимает HttpContext объект и возвращает Taskобъект. Делегат пишет "Hello world!" в ответ.
  • app.Run() Второй запускает приложение.

Когда приложение получает HTTP-запрос, делегат вызывается. Делегат записывает сообщение "Hello world!" в ответ и завершает запрос.

По промежуточному по промежуточному слоям цепочки

В большинстве приложений есть несколько компонентов ПО промежуточного слоя, которые выполняются в последовательности. Порядок добавления компонентов ПО промежуточного слоя в конвейер важен. Компоненты выполняются в том порядке, в который они были добавлены.

Терминал и нетерминальное ПО промежуточного слоя

Каждое ПО промежуточного слоя можно рассматривать как терминал или нетерминальное. Нетерминальное ПО промежуточного слоя обрабатывает запрос, а затем вызывает следующее ПО промежуточного слоя в конвейере. ПО промежуточного слоя терминала является последним ПО промежуточного слоя в конвейере и не имеет следующего ПО промежуточного слоя для вызова.

Делегаты, добавленные с app.Use() помощью, могут быть терминалом или нетерминальным ПО промежуточного слоя. Эти делегаты ожидают HttpContext объект и RequestDelegate объект в качестве параметров. Обычно делегат включает await next.Invoke();. Этот элемент управления передается следующему ПО промежуточного слоя конвейера. Код перед выполнением этой строки до следующего ПО промежуточного слоя и кода после выполнения следующей строки по промежуточному слоям. Делегат, добавленный с app.Use() двумя возможностями для выполнения запроса перед отправкой ответа клиенту; после создания ответа по промежуточному по промежуточному слоя терминала и снова после создания ответа по промежуточному слоям терминала.

Делегаты, добавленные с app.Run() помощью, всегда являются по промежуточному слоям терминала. Они не вызывают следующее ПО промежуточного слоя в конвейере. Это последний компонент по промежуточного слоя, который выполняется. Они ожидают HttpContext только объект в качестве параметра. app.Run() — это ярлык для добавления по промежуточного слоя терминала.

Рассмотрим следующий пример:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello from middleware 1. Passing to the next middleware!\r\n");

    // Call the next middleware in the pipeline
    await next.Invoke();

    await context.Response.WriteAsync("Hello from middleware 1 again!\r\n");
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from middleware 2!\r\n");
});

app.Run();

В предыдущем коде:

  • app.Use() определяет компонент ПО промежуточного слоя, который:
    • Записывает сообщение "Hello from middleware 1. Передача в следующее ПО промежуточного слоя!" в ответ.
    • Передает запрос следующему компоненту по промежуточного слоя в конвейере и ожидает завершения работы с await next.Invoke()ним.
    • После завершения следующего компонента в конвейере он записывает сообщение "Hello from middleware 1 again!"
  • Первый app.Run() определяет компонент ПО промежуточного слоя, который записывает сообщение "Hello from middleware 2!" в ответ.
  • app.Run() Второй запускает приложение.

Во время выполнения, когда веб-браузер отправляет запрос в это приложение, компоненты по промежуточного слоя выполняются в том порядке, в который они были добавлены в конвейер. Приложение возвращает следующий ответ:

Hello from middleware 1. Passing to the next middleware!
Hello from middleware 2!
Hello from middleware 1 again!

Встроенное ПО промежуточного слоя

ASP.NET Core предоставляет набор встроенных компонентов ПО промежуточного слоя, которые можно использовать для добавления общих функций в приложение. Помимо явно добавленных компонентов ПО промежуточного слоя некоторые по промежуточному слоям неявно добавляются для вас по умолчанию. Например, WebApplication.CreateBuilder() возвращает по промежуточному WebApplicationBuilder слоя маршрутизации страницы исключений разработчика, условно добавляет ПО промежуточного слоя проверки подлинности и авторизации при настройке связанных служб и добавляет ПО промежуточного слоя маршрутизации конечных точек.

Например, рассмотрим следующий файл Program.cs :

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

В предыдущем коде:

  • app.UseExceptionHandler() добавляет компонент ПО промежуточного слоя, который перехватывает исключения и возвращает страницу ошибок.
  • app.UseHsts() добавляет компонент ПО промежуточного слоя, который задает заголовок Strict-Transport-Security.
  • app.UseHttpsRedirection() добавляет компонент ПО промежуточного слоя, который перенаправляет HTTP-запросы на HTTPS.
  • app.UseAntiforgery() добавляет компонент ПО промежуточного слоя, который предотвращает атаки межсайтовых запросов на подделку (CSRF).
  • app.MapStaticAssets() и app.MapRazorComponents<App>() сопоставляйте маршруты к конечным точкам, которые затем обрабатываются ПО промежуточного слоя маршрутизации конечных точек. ПО промежуточного слоя маршрутизации конечных точек неявно добавляется WebApplicationBuilder.

Существует множество встроенных компонентов по промежуточного слоя, которые можно использовать в приложении в зависимости от типа приложения и ваших потребностей. Ознакомьтесь с документацией по полному списку.

Совет

В этом контексте методы, начинающиеся с Use , обычно предназначены для сопоставления ПО промежуточного слоя. Методы, начинающиеся с Map , как правило, предназначены для сопоставления конечных точек.

Внимание

Компоненты ПО промежуточного слоя заказа добавляются в конвейер! Перед правильной работой некоторых компонентов ПО промежуточного слоя должны выполняться другие компоненты. Проверьте документацию по каждому компоненту по промежуточного слоя, чтобы определить правильный порядок.