ПО промежуточного слоя ASP.NET CoreASP.NET Core Middleware

Авторы: Рик Андерсон (Rick Anderson) и Стив Смит (Steve Smith)By Rick Anderson and Steve Smith

ПО промежуточного слоя — это программное обеспечение, выстраиваемое в виде конвейера приложения для обработки запросов и откликов.Middleware is software that's assembled into an app pipeline to handle requests and responses. Каждый компонент:Each component:

  • определяет, нужно ли передать запрос следующему компоненту в конвейере;Chooses whether to pass the request to the next component in the pipeline.
  • может выполнять работу как до, так и после вызова следующего компонента в конвейере.Can perform work before and after the next component in the pipeline.

Для построения конвейера запросов используются делегаты запроса.Request delegates are used to build the request pipeline. Они обрабатывают каждый HTTP-запрос.The request delegates handle each HTTP request.

Для их настройки служат методы расширения Run, Map и Use.Request delegates are configured using Run, Map, and Use extension methods. Отдельный делегат запроса можно указать встроенным в качестве анонимного метода (называемого встроенным ПО промежуточного слоя) либо определить в многоразовом классе.An individual request delegate can be specified in-line as an anonymous method (called in-line middleware), or it can be defined in a reusable class. Эти многоразовые классы и встроенные анонимные методы являются ПО промежуточного слоя или компонентами промежуточного слоя .These reusable classes and in-line anonymous methods are middleware , also called middleware components . Каждый компонент ПО промежуточного слоя в конвейере запросов отвечает за вызов следующего компонента в конвейере или замыкает конвейер.Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the pipeline. Когда промежуточный слой замыкает конвейер, он становится терминальным промежуточным слоем , так как препятствует обработке запроса дальнейшими компонентами промежуточного слоя.When a middleware short-circuits, it's called a terminal middleware because it prevents further middleware from processing the request.

В статье Миграция обработчиков и модулей HTTP в ASP.NET Core по промежуточного слоя поясняются различия между конвейерами запросов в ASP.NET Core и ASP.NET 4.x, а также приводятся дополнительные примеры ПО промежуточного слоя.Миграция обработчиков и модулей HTTP в ASP.NET Core по промежуточного слоя explains the difference between request pipelines in ASP.NET Core and ASP.NET 4.x and provides additional middleware samples.

Создание конвейера ПО промежуточного слоя с помощью IApplicationBuilderCreate a middleware pipeline with IApplicationBuilder

Конвейер запросов ASP.NET Core состоит из последовательности делегатов запроса, вызываемых один за другим.The ASP.NET Core request pipeline consists of a sequence of request delegates, called one after the other. На следующей схеме демонстрируется этот принцип.The following diagram demonstrates the concept. Поток выполнения показан черными стрелками.The thread of execution follows the black arrows.

Шаблон обработки запросов, показывающий входящий запрос, обработку в трех компонентах промежуточного слоя и запрос, покидающий приложение.

Каждый из делегатов может выполнять операции до и после следующего делегата.Each delegate can perform operations before and after the next delegate. Делегаты обработки исключений должны вызываться в начале конвейера, чтобы перехватывать исключения, возникающие на более поздних этапах.Exception-handling delegates should be called early in the pipeline, so they can catch exceptions that occur in later stages of the pipeline.

Простейшее приложение ASP.NET Core задает один делегат запроса, обрабатывающий все запросы.The simplest possible ASP.NET Core app sets up a single request delegate that handles all requests. В этом случае конвейер запросов как таковой отсутствует.This case doesn't include an actual request pipeline. Вместо этого в ответ на каждый HTTP-запрос вызывается одна анонимная функция.Instead, a single anonymous function is called in response to every HTTP request.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}

Несколько делегатов запроса можно соединить в цепочку с помощью Use.Chain multiple request delegates together with Use. Параметр next представляет следующий делегат в конвейере.The next parameter represents the next delegate in the pipeline. Замыкать конвейер можно не вызывая параметр next .You can short-circuit the pipeline by not calling the next parameter. Обычно действия можно выполнять как до, так и после следующего делегата, как показано в этом примере.You can typically perform actions both before and after the next delegate, as the following example demonstrates:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

Если делегат не передает запрос следующему делегату, это называется замыканием конвейера запросов .When a delegate doesn't pass a request to the next delegate, it's called short-circuiting the request pipeline . Замыкание часто является предпочтительным, так как позволяет избежать ненужной работы.Short-circuiting is often desirable because it avoids unnecessary work. Например, компонент промежуточного слоя для статических файлов может выступать в роли терминального промежуточного слоя , обрабатывая запрос статического файла и замыкая оставшуюся часть конвейера.For example, Static File Middleware can act as a terminal middleware by processing a request for a static file and short-circuiting the rest of the pipeline. Компоненты промежуточного слоя, предшествующие терминальному промежуточному слою, по-прежнему обрабатывают код после их инструкций next.Invoke.Middleware added to the pipeline before the middleware that terminates further processing still processes code after their next.Invoke statements. Но учитывайте следующее предупреждение о попытке записи в ответ, который уже был отправлен.However, see the following warning about attempting to write to a response that has already been sent.

Предупреждение

Не вызывайте next.Invoke после отправки отклика клиенту.Don't call next.Invoke after the response has been sent to the client. Изменения HttpResponse после запуска отклика приведут к возникновению исключения.Changes to HttpResponse after the response has started throw an exception. Таким изменением может быть задание заголовков и кода состояния.For example, setting headers and a status code throw an exception. Запись в тело отклика после вызова next:Writing to the response body after calling next:

  • может вызвать нарушение протокола,May cause a protocol violation. например, при записи больше указанного значения Content-Length;For example, writing more than the stated Content-Length.
  • может привести к нарушению формата,May corrupt the body format. например, при записи нижнего колонтитула HTML в CSS-файл.For example, writing an HTML footer to a CSS file.

HasStarted удобно использовать для обозначения того, были ли отправлены заголовки или выполнена запись в тело отклика.HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.

Делегаты Run не получают параметр next.Run delegates don't receive a next parameter. Первый делегат Run всегда является конечным и завершает конвейер.The first Run delegate is always terminal and terminates the pipeline. Run является соглашение.Run is a convention. Некоторые компоненты промежуточного слоя могут предоставлять методы Run[Middleware], которые выполняются в конце конвейера:Some middleware components may expose Run[Middleware] methods that run at the end of the pipeline:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

Если вы хотите увидеть комментарии к коду, переведенные на языки, отличные от английского, сообщите нам на странице обсуждения этой проблемы на сайте GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

В предыдущем примере делегат Run записывает "Hello from 2nd delegate." в ответ и завершает конвейер.In the preceding example, the Run delegate writes "Hello from 2nd delegate." to the response and then terminates the pipeline. Если добавить другой делегат Use или Run после делегата Run, он не будет вызван.If another Use or Run delegate is added after the Run delegate, it's not called.

Порядок ПО промежуточного слояMiddleware order

На следующей схеме показан полный конвейер обработки запросов для приложений ASP.NET Core MVC и Razor Pages.The following diagram shows the complete request processing pipeline for ASP.NET Core MVC and Razor Pages apps. Здесь демонстрируется порядок размещения ПО промежуточного слоя и этапы, на которых добавляется пользовательское ПО промежуточного слоя, в стандартном приложении.You can see how, in a typical app, existing middlewares are ordered and where custom middlewares are added. Вы можете полностью контролировать изменение порядка существующего ПО промежуточного слоя или внедрять новое пользовательское ПО промежуточного слоя для своих сценариев.You have full control over how to reorder existing middlewares or inject new custom middlewares as necessary for your scenarios.

Конвейер ПО промежуточного слоя ASP.NET Core

ПО промежуточного слоя конечной точки на предыдущей схеме выполняет конвейер фильтра для соответствующего типа приложения — MVC или Razor Pages.The Endpoint middleware in the preceding diagram executes the filter pipeline for the corresponding app type—MVC or Razor Pages.

Конвейер фильтра ASP.NET Core

Порядок, в котором компоненты промежуточного слоя добавляются в метод Startup.Configure, определяет порядок их вызова при запросах и обратный порядок для отклика.The order that middleware components are added in the Startup.Configure method defines the order in which the middleware components are invoked on requests and the reverse order for the response. Соблюдать этот порядок крайне важно для обеспечения безопасности, производительности и функциональности.The order is critical for security, performance, and functionality.

Следующий метод Startup.Configure добавляет связанные с безопасностью компоненты ПО промежуточного слоя в рекомендуемом порядке:The following Startup.Configure method adds security-related middleware components in the recommended order:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    // app.UseCookiePolicy();

    app.UseRouting();
    // app.UseRequestLocalization();
    // app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();
    // app.UseSession();
    // app.UseResponseCaching();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

В приведенном выше коде:In the preceding code:

  • ПО промежуточного слоя, которое не было добавлено при создании веб-приложения с учетными записями отдельных пользователей, деактивируется.Middleware that is not added when creating a new web app with individual users accounts is commented out.
  • Этот порядок должен соблюдаться не для любого ПО промежуточного слоя.Not every middleware needs to go in this exact order, but many do. Пример:For example:
    • UseCors, UseAuthenticationи UseAuthorization нужно использовать в указанном порядке.UseCors, UseAuthentication, and UseAuthorization must go in the order shown.
    • UseCors сейчас нужно использовать перед UseResponseCaching из-за этой ошибки.UseCors currently must go before UseResponseCaching due to this bug.

Метод Startup.Configure добавляет компоненты ПО промежуточного слоя для распространенных сценариев приложений:The following Startup.Configure method adds middleware components for common app scenarios:

  1. Обработка исключений/ошибокException/error handling
    • Когда приложение выполняется в среде разработки:When the app runs in the Development environment:
      • ПО промежуточного слоя страницы исключений для разработчика (UseDeveloperExceptionPage) сообщает об ошибках среды выполнения приложения.Developer Exception Page Middleware (UseDeveloperExceptionPage) reports app runtime errors.
      • ПО промежуточного слоя страницы исключений для базы данных сообщает об ошибках среды выполнения базы данных.Database Error Page Middleware reports database runtime errors.
    • Когда приложение выполняется в рабочей среде:When the app runs in the Production environment:
      • ПО промежуточного слоя обработчика исключений (UseExceptionHandler) перехватывает исключения, возникшие в указанном ниже ПО промежуточного слоя.Exception Handler Middleware (UseExceptionHandler) catches exceptions thrown in the following middlewares.
      • ПО промежуточного слоя протокола HTTP Strict Transport Security Protocol (HSTS) (UseHsts) добавляет заголовок Strict-Transport-Security.HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) adds the Strict-Transport-Security header.
  2. ПО промежуточного слоя перенаправления HTTPS (UseHttpsRedirection) перенаправляет запросы с HTTP на HTTPS.HTTPS Redirection Middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.
  3. ПО промежуточного слоя статических файлов (UseStaticFiles) возвращает статические файлы и сокращает дальнейшую обработку запросов.Static File Middleware (UseStaticFiles) returns static files and short-circuits further request processing.
  4. ПО промежуточного слоя политики файлов Cookie (UseCookiePolicy) обеспечивает соответствие приложения нормам Общего регламента по защите данных (GDPR) ЕС.Cookie Policy Middleware (UseCookiePolicy) conforms the app to the EU General Data Protection Regulation (GDPR) regulations.
  5. ПО промежуточного слоя маршрутизации (UseRouting) для маршрутизации запросов.Routing Middleware (UseRouting) to route requests.
  6. ПО промежуточного слоя проверки подлинности (UseAuthentication) пытается проверить подлинность пользователя, прежде чем предоставить ему доступ к защищенным ресурсам.Authentication Middleware (UseAuthentication) attempts to authenticate the user before they're allowed access to secure resources.
  7. ПО промежуточного слоя авторизации (UseAuthorization) разрешает пользователю доступ к защищенным ресурсам.Authorization Middleware (UseAuthorization) authorizes a user to access secure resources.
  8. ПО промежуточного слоя сеанса (UseSession) устанавливает и поддерживает состояние сеанса.Session Middleware (UseSession) establishes and maintains session state. Если в приложении используется состояние сеанса, вызовите ПО промежуточного слоя сеанса после ПО промежуточного слоя политики файлов Cookie и до ПО промежуточного слоя MVC.If the app uses session state, call Session Middleware after Cookie Policy Middleware and before MVC Middleware.
  9. ПО промежуточного слоя маршрутизации конечных точек (UseEndpoints с MapRazorPages) для добавления конечных точек Razor Pages в конвейер запросов.Endpoint Routing Middleware (UseEndpoints with MapRazorPages) to add Razor Pages endpoints to the request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

В предыдущем примере кода каждый метод расширения ПО промежуточного слоя представляется в IApplicationBuilder с использованием пространства имен Microsoft.AspNetCore.Builder.In the preceding example code, each middleware extension method is exposed on IApplicationBuilder through the Microsoft.AspNetCore.Builder namespace.

UseExceptionHandler — это первый компонент промежуточного слоя, добавленный в конвейер.UseExceptionHandler is the first middleware component added to the pipeline. Таким образом, обработчик исключений ПО промежуточного слоя перехватывает все исключения, возникающие в последующих вызовах.Therefore, the Exception Handler Middleware catches any exceptions that occur in later calls.

Компонент промежуточного слоя для статических файлов вызывается на раннем этапе конвейера, чтобы он мог обработать запросы и выполнить замыкание, минуя остальные компоненты.Static File Middleware is called early in the pipeline so that it can handle requests and short-circuit without going through the remaining components. Этот компонент не выполняет проверки авторизации.The Static File Middleware provides no authorization checks. Все обрабатываемые им файлы, включая расположенные в wwwroot , находятся в открытом доступе.Any files served by Static File Middleware, including those under wwwroot , are publicly available. Сведения о защите статических файлов см. в статье Статические файлы в ASP.NET Core.For an approach to secure static files, see Статические файлы в ASP.NET Core.

Если запрос не обрабатывается компонентом промежуточного слоя для статических файлов, он передается в компонент промежуточного слоя для проверки подлинности (UseAuthentication), который выполняет проверку подлинности.If the request isn't handled by the Static File Middleware, it's passed on to the Authentication Middleware (UseAuthentication), which performs authentication. Этот компонент не замыкает запросы, не прошедшие проверку подлинности.Authentication doesn't short-circuit unauthenticated requests. Хотя ПО промежуточного слоя для проверки подлинности проверяет подлинность запросов, авторизация (и отклонение) выполняются только после того, как MVC выберет указанную страницу Razor Pages или контроллер MVC и действие.Although Authentication Middleware authenticates requests, authorization (and rejection) occurs only after MVC selects a specific Razor Page or MVC controller and action.

Следующий пример показывает порядок компонентов промежуточного слоя, где запросы для статических файлов обрабатываются компонентом для статических файлов до компонента для сжатия откликов.The following example demonstrates a middleware order where requests for static files are handled by Static File Middleware before Response Compression Middleware. Статические файлы не сжимаются с этим порядком ПО промежуточного слоя.Static files aren't compressed with this middleware order. Ответы Razor Pages могут быть сжаты.The Razor Pages responses can be compressed.

public void Configure(IApplicationBuilder app)
{
    // Static files aren't compressed by Static File Middleware.
    app.UseStaticFiles();

    app.UseResponseCompression();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Для одностраничных приложений (SPA) ПО промежуточного слоя SPA UseSpaStaticFiles обычно поступает в конвейер ПО промежуточного слоя последним.For Single Page Applications (SPAs), the SPA middleware UseSpaStaticFiles usually comes last in the middleware pipeline. ПО промежуточного слоя SPA поступает последним:The SPA middleware comes last:

  • Чтобы разрешить остальным ПО промежуточного слоя отвечать на запросы сопоставления в первую очередь.To allow all other middlewares to respond to matching requests first.
  • Чтобы разрешить одностраничным приложениям с маршрутизацией на стороне клиента выполняться для всех маршрутов, не распознаваемых серверным приложением.To allow SPAs with client-side routing to run for all routes that are unrecognized by the server app.

Дополнительные сведения об SPA см. в руководствах по шаблонам проектов React и Angular.For more details on SPAs, see the guides for the React and Angular project templates.

Порядок ПО промежуточного слоя перенаправления заголовковForwarded Headers Middleware order

ПО промежуточного слоя перенаправления заголовков должно выполняться до другого ПО промежуточного слоя.Forwarded Headers Middleware should run before other middleware. Такой порядок гарантирует, что ПО промежуточного слоя, полагающееся на сведения о перенаправленных заголовках, может использовать значения заголовков для обработки.This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing. Сведения о запуске ПО промежуточного слоя перенаправления заголовков после ПО промежуточного слоя диагностики и обработки ошибок см. в разделе Порядок ПО промежуточного слоя перенаправления заголовков.To run Forwarded Headers Middleware after diagnostics and error handling middleware, see Forwarded Headers Middleware order.

Ветвление конвейера ПО промежуточного слояBranch the middleware pipeline

Расширения Map используются в качестве соглашения для ветвления конвейера.Map extensions are used as a convention for branching the pipeline. Map осуществляет ветвление конвейера запросов на основе совпадений для заданного пути запроса.Map branches the request pipeline based on matches of the given request path. Если путь запроса начинается с заданного пути, данная ветвь выполняется.If the request path starts with the given path, the branch is executed.

public class Startup
{
    private static void HandleMapTest1(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 1");
        });
    }

    private static void HandleMapTest2(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 2");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1", HandleMapTest1);

        app.Map("/map2", HandleMapTest2);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}

Ниже приведены запросы и отклики http://localhost:1234 на базе предыдущего кода.The following table shows the requests and responses from http://localhost:1234 using the previous code.

ЗапросRequest ОтветResponse
localhost:1234localhost:1234 Hello from non-Map delegate.Hello from non-Map delegate.
localhost:1234/map1localhost:1234/map1 Map Test 1Map Test 1
localhost:1234/map2localhost:1234/map2 Map Test 2Map Test 2
localhost:1234/map3localhost:1234/map3 Hello from non-Map delegate.Hello from non-Map delegate.

Когда используется Map, соответствующие сегменты путей удаляются из HttpRequest.Path и добавляются к HttpRequest.PathBase для каждого запроса.When Map is used, the matched path segments are removed from HttpRequest.Path and appended to HttpRequest.PathBase for each request.

Map поддерживает вложение, например:Map supports nesting, for example:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map также может сопоставить несколько сегментов одновременно:Map can also match multiple segments at once:

public class Startup
{
    private static void HandleMultiSeg(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map multiple segments.");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1/seg1", HandleMultiSeg);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate.");
        });
    }
}

MapWhen осуществляет ветвление конвейера запросов на основе результата заданного предиката.MapWhen branches the request pipeline based on the result of the given predicate. Любой предикат типа Func<HttpContext, bool> можно использовать для сопоставления запросов с новой ветвью конвейера.Any predicate of type Func<HttpContext, bool> can be used to map requests to a new branch of the pipeline. В следующем примере предикат служит для определения наличия переменной строки запроса branch.In the following example, a predicate is used to detect the presence of a query string variable branch:

public class Startup
{
    private static void HandleBranch(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            var branchVer = context.Request.Query["branch"];
            await context.Response.WriteAsync($"Branch used = {branchVer}");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
                               HandleBranch);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}

Ниже приведены запросы и отклики http://localhost:1234 на базе предыдущего кода.The following table shows the requests and responses from http://localhost:1234 using the previous code:

ЗапросRequest ОтветResponse
localhost:1234localhost:1234 Hello from non-Map delegate.Hello from non-Map delegate.
localhost:1234/?branch=masterlocalhost:1234/?branch=master Branch used = masterBranch used = master

UseWhen также осуществляет ветвление конвейера запросов на основе результата заданного предиката.UseWhen also branches the request pipeline based on the result of the given predicate. В отличие от MapWhen, эта ветвь снова объединяется с основным конвейером, если она не выполняется по сокращенной схеме или не содержит конечное ПО промежуточного слоя:Unlike with MapWhen, this branch is rejoined to the main pipeline if it doesn't short-circuit or contain a terminal middleware:

public class Startup
{
    private void HandleBranchAndRejoin(IApplicationBuilder app, ILogger<Startup> logger)
    {
        app.Use(async (context, next) =>
        {
            var branchVer = context.Request.Query["branch"];
            logger.LogInformation("Branch used = {branchVer}", branchVer);

            // Do work that doesn't write to the Response.
            await next();
            // Do other work that doesn't write to the Response.
        });
    }

    public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
    {
        app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
                               appBuilder => HandleBranchAndRejoin(appBuilder, logger));

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from main pipeline.");
        });
    }
}

В предыдущем примере ответ "Hello from main pipeline."In the preceding example, a response of "Hello from main pipeline." записывается для всех запросов.is written for all requests. Если запрос включает переменную строки запроса branch, ее значение регистрируется до того, как будет выполнено повторное объединение с основным конвейером.If the request includes a query string variable branch, its value is logged before the main pipeline is rejoined.

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

ASP.NET Core содержит следующие компоненты промежуточного слоя.ASP.NET Core ships with the following middleware components. В столбце Порядок указаны сведения о размещении ПО промежуточного слоя в конвейере обработки запросов и условия, в соответствии с которыми ПО промежуточного слоя может прервать обработку запроса.The Order column provides notes on middleware placement in the request processing pipeline and under what conditions the middleware may terminate request processing. Если промежуточный слой замыкает конвейер обработки запроса и препятствует обработке запроса дальнейшими компонентами промежуточного слоя, он называется терминальным промежуточным слоем .When a middleware short-circuits the request processing pipeline and prevents further downstream middleware from processing a request, it's called a terminal middleware . Дополнительные сведения о замыкании конвейера см. в разделе Создание конвейера ПО промежуточного слоя с помощью IApplicationBuilder.For more information on short-circuiting, see the Create a middleware pipeline with IApplicationBuilder section.

ПО промежуточного слояMiddleware ОписаниеDescription НомерOrder
AuthenticationAuthentication Обеспечивает поддержку проверки подлинности.Provides authentication support. Ставится перед тем, как потребуется HttpContext.User.Before HttpContext.User is needed. Является конечным для обратных вызовов OAuth.Terminal for OAuth callbacks.
АвторизацияAuthorization Обеспечивает поддержку авторизации.Provides authorization support. Непосредственно после ПО промежуточного слоя для проверки подлинности.Immediately after the Authentication Middleware.
Политика CookieCookie Policy Позволяет отслеживать согласие пользователей на хранение личных сведений и применять минимальные стандарты для полей файлов cookie, таких как secure и SameSite.Tracks consent from users for storing personal information and enforces minimum standards for cookie fields, such as secure and SameSite. Перед ПО промежуточного слоя, которое использует файлы cookie.Before middleware that issues cookies. Примеры Authentication, Session, MVC (TempData).Examples: Authentication, Session, MVC (TempData).
CORSCORS Настраивает общий доступ к ресурсам независимо от источника.Configures Cross-Origin Resource Sharing. Ставится перед компонентами, использующими CORS.Before components that use CORS. UseCors сейчас нужно использовать перед UseResponseCaching из-за этой ошибки.UseCors currently must go before UseResponseCaching due to this bug.
Error HandlingDiagnostics Отдельное ПО промежуточного слоя, которое обеспечивает обработку исключений, предоставляет страницу исключений для разработчика, страницы состояния кода, веб-страницу по умолчанию для новых приложений.Several separate middlewares that provide a developer exception page, exception handling, status code pages, and the default web page for new apps. Ставится перед компонентами, выдающими ошибки.Before components that generate errors. Является конечным для исключений или обслуживания веб-страницы по умолчанию для новых приложений.Terminal for exceptions or serving the default web page for new apps.
Forwarded HeadersForwarded Headers Пересылает заголовки, переданные через прокси-сервер, в текущий запрос.Forwards proxied headers onto the current request. Перед компонентами, использующими обновленные поля.Before components that consume the updated fields. Например: схема, узел, IP-адрес клиента, метод.Examples: scheme, host, client IP, method.
Проверка работоспособностиHealth Check Проверяет работоспособность приложения ASP.NET Core и его зависимостей, таких как проверка доступности базы данных.Checks the health of an ASP.NET Core app and its dependencies, such as checking database availability. Является конечным, если запрос соответствует конечной точке проверки работоспособности.Terminal if a request matches a health check endpoint.
Распространение заголовковHeader Propagation Распространяет заголовки HTTP из входящего запроса на исходящие запросы HTTP-клиентов.Propagates HTTP headers from the incoming request to the outgoing HTTP Client requests.
HTTP Method OverrideHTTP Method Override Разрешает входящий запрос POST для переопределения этого метода.Allows an incoming POST request to override the method. Ставится перед компонентами, использующими обновленный метод.Before components that consume the updated method.
HTTPS RedirectionHTTPS Redirection Перенаправляет все запросы HTTP на HTTPS.Redirect all HTTP requests to HTTPS. Ставится перед компонентами, использующими URL-адрес.Before components that consume the URL.
HTTP Strict Transport Security (HSTS)HTTP Strict Transport Security (HSTS) ПО промежуточного слоя для повышения безопасности, которое добавляет специальный заголовок ответа.Security enhancement middleware that adds a special response header. Перед отправкой ответов и после компонентов, изменяющих запросы.Before responses are sent and after components that modify requests. Примеры Forwarded Headers, URL Rewriting.Examples: Forwarded Headers, URL Rewriting.
MVCMVC Обрабатывает запросы с помощью MVC либо Razor Pages.Processes requests with MVC/Razor Pages. Является конечным, если запрос соответствует маршруту.Terminal if a request matches a route.
OWINOWIN Взаимодействие с приложениями, серверами и ПО промежуточного слоя на основе OWIN.Interop with OWIN-based apps, servers, and middleware. Является конечным, если ПО промежуточного слоя OWIN полностью обрабатывает запрос.Terminal if the OWIN Middleware fully processes the request.
Кэширование ответовResponse Caching Обеспечивает поддержку для кэширования откликов.Provides support for caching responses. Ставится перед компонентами, требующими кэширование.Before components that require caching. UseCORS нужно использовать перед UseResponseCaching.UseCORS must come before UseResponseCaching.
Сжатие откликовResponse Compression Обеспечивает поддержку для сжатия откликов.Provides support for compressing responses. Ставится перед компонентами, требующими сжатие.Before components that require compression.
LocalizationRequest Localization Обеспечивает поддержку локализации.Provides localization support. Ставится перед компонентами, для которых важна локализация.Before localization sensitive components.
Маршрутизация конечных точекEndpoint Routing Определяет и ограничивает маршруты запросов.Defines and constrains request routes. Является конечным для совпадающих маршрутов.Terminal for matching routes.
Безопасная проверка пароляSPA Обрабатывает все запросы от этой точки в цепочке ПО промежуточного слоя, возвращая страницу по умолчанию для одностраничного приложения (SPA)Handles all requests from this point in the middleware chain by returning the default page for the Single Page Application (SPA) В конце цепочки, чтобы другое ПО промежуточного слоя для обслуживания статических файлов, действий MVC и т. д. имело приоритет.Late in the chain, so that other middleware for serving static files, MVC actions, etc., takes precedence.
SessionSession Обеспечивает поддержку для управления пользовательскими сеансами.Provides support for managing user sessions. Ставится перед компонентами, требующими сеанс.Before components that require Session.
Static FilesStatic Files Обеспечивает поддержку для обработки статических файлов и просмотра каталогов.Provides support for serving static files and directory browsing. Является конечным, если запрос соответствует файлу.Terminal if a request matches a file.
Переопределение URL-адресовURL Rewrite Обеспечивает поддержку для переопределения URL-адресов и перенаправления запросов.Provides support for rewriting URLs and redirecting requests. Ставится перед компонентами, использующими URL-адрес.Before components that consume the URL.
WebSocketsWebSockets Обеспечивает поддержку протокола WebSockets.Enables the WebSockets protocol. Ставится перед компонентами, которым нужно принимать запросы WebSocket.Before components that are required to accept WebSocket requests.

Дополнительные ресурсыAdditional resources

Авторы: Рик Андерсон (Rick Anderson) и Стив Смит (Steve Smith)By Rick Anderson and Steve Smith

ПО промежуточного слоя — это программное обеспечение, выстраиваемое в виде конвейера приложения для обработки запросов и откликов.Middleware is software that's assembled into an app pipeline to handle requests and responses. Каждый компонент:Each component:

  • определяет, нужно ли передать запрос следующему компоненту в конвейере;Chooses whether to pass the request to the next component in the pipeline.
  • может выполнять работу как до, так и после вызова следующего компонента в конвейере.Can perform work before and after the next component in the pipeline.

Для построения конвейера запросов используются делегаты запроса.Request delegates are used to build the request pipeline. Они обрабатывают каждый HTTP-запрос.The request delegates handle each HTTP request.

Для их настройки служат методы расширения Run, Map и Use.Request delegates are configured using Run, Map, and Use extension methods. Отдельный делегат запроса можно указать встроенным в качестве анонимного метода (называемого встроенным ПО промежуточного слоя) либо определить в многоразовом классе.An individual request delegate can be specified in-line as an anonymous method (called in-line middleware), or it can be defined in a reusable class. Эти многоразовые классы и встроенные анонимные методы являются ПО промежуточного слоя или компонентами промежуточного слоя .These reusable classes and in-line anonymous methods are middleware , also called middleware components . Каждый компонент ПО промежуточного слоя в конвейере запросов отвечает за вызов следующего компонента в конвейере или замыкает конвейер.Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the pipeline. Когда промежуточный слой замыкает конвейер, он становится терминальным промежуточным слоем , так как препятствует обработке запроса дальнейшими компонентами промежуточного слоя.When a middleware short-circuits, it's called a terminal middleware because it prevents further middleware from processing the request.

В статье Миграция обработчиков и модулей HTTP в ASP.NET Core по промежуточного слоя поясняются различия между конвейерами запросов в ASP.NET Core и ASP.NET 4.x, а также приводятся дополнительные примеры ПО промежуточного слоя.Миграция обработчиков и модулей HTTP в ASP.NET Core по промежуточного слоя explains the difference between request pipelines in ASP.NET Core and ASP.NET 4.x and provides additional middleware samples.

Создание конвейера ПО промежуточного слоя с помощью IApplicationBuilderCreate a middleware pipeline with IApplicationBuilder

Конвейер запросов ASP.NET Core состоит из последовательности делегатов запроса, вызываемых один за другим.The ASP.NET Core request pipeline consists of a sequence of request delegates, called one after the other. На следующей схеме демонстрируется этот принцип.The following diagram demonstrates the concept. Поток выполнения показан черными стрелками.The thread of execution follows the black arrows.

Шаблон обработки запросов, показывающий входящий запрос, обработку в трех компонентах промежуточного слоя и запрос, покидающий приложение.

Каждый из делегатов может выполнять операции до и после следующего делегата.Each delegate can perform operations before and after the next delegate. Делегаты обработки исключений должны вызываться в начале конвейера, чтобы перехватывать исключения, возникающие на более поздних этапах.Exception-handling delegates should be called early in the pipeline, so they can catch exceptions that occur in later stages of the pipeline.

Простейшее приложение ASP.NET Core задает один делегат запроса, обрабатывающий все запросы.The simplest possible ASP.NET Core app sets up a single request delegate that handles all requests. В этом случае конвейер запросов как таковой отсутствует.This case doesn't include an actual request pipeline. Вместо этого в ответ на каждый HTTP-запрос вызывается одна анонимная функция.Instead, a single anonymous function is called in response to every HTTP request.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}

Первый делегат Run завершает конвейер.The first Run delegate terminates the pipeline.

Несколько делегатов запроса можно соединить в цепочку с помощью Use.Chain multiple request delegates together with Use. Параметр next представляет следующий делегат в конвейере.The next parameter represents the next delegate in the pipeline. Замыкать конвейер можно не вызывая параметр next .You can short-circuit the pipeline by not calling the next parameter. Обычно действия можно выполнять как до, так и после следующего делегата, как показано в этом примере.You can typically perform actions both before and after the next delegate, as the following example demonstrates:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

Если делегат не передает запрос следующему делегату, это называется замыканием конвейера запросов .When a delegate doesn't pass a request to the next delegate, it's called short-circuiting the request pipeline . Замыкание часто является предпочтительным, так как позволяет избежать ненужной работы.Short-circuiting is often desirable because it avoids unnecessary work. Например, компонент промежуточного слоя для статических файлов может выступать в роли терминального промежуточного слоя , обрабатывая запрос статического файла и замыкая оставшуюся часть конвейера.For example, Static File Middleware can act as a terminal middleware by processing a request for a static file and short-circuiting the rest of the pipeline. Компоненты промежуточного слоя, предшествующие терминальному промежуточному слою, по-прежнему обрабатывают код после их инструкций next.Invoke.Middleware added to the pipeline before the middleware that terminates further processing still processes code after their next.Invoke statements. Но учитывайте следующее предупреждение о попытке записи в ответ, который уже был отправлен.However, see the following warning about attempting to write to a response that has already been sent.

Предупреждение

Не вызывайте next.Invoke после отправки отклика клиенту.Don't call next.Invoke after the response has been sent to the client. Изменения HttpResponse после запуска отклика приведут к возникновению исключения.Changes to HttpResponse after the response has started throw an exception. Например, таким изменением может быть задание HTTP-заголовков и кода состояния.For example, changes such as setting headers and a status code throw an exception. Запись в тело отклика после вызова next:Writing to the response body after calling next:

  • может вызвать нарушение протокола,May cause a protocol violation. например, при записи больше указанного значения Content-Length;For example, writing more than the stated Content-Length.
  • может привести к нарушению формата,May corrupt the body format. например, при записи нижнего колонтитула HTML в CSS-файл.For example, writing an HTML footer to a CSS file.

HasStarted удобно использовать для обозначения того, были ли отправлены заголовки или выполнена запись в тело отклика.HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.

Порядок ПО промежуточного слояMiddleware order

Порядок, в котором компоненты промежуточного слоя добавляются в метод Startup.Configure, определяет порядок их вызова при запросах и обратный порядок для отклика.The order that middleware components are added in the Startup.Configure method defines the order in which the middleware components are invoked on requests and the reverse order for the response. Соблюдать этот порядок крайне важно для обеспечения безопасности, производительности и функциональности.The order is critical for security, performance, and functionality.

Следующий метод Startup.Configure добавляет связанные с безопасностью компоненты ПО промежуточного слоя в рекомендуемом порядке:The following Startup.Configure method adds security related middleware components in the recommended order:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    // app.UseRequestLocalization();
    // app.UseCors();

    app.UseAuthentication();
    // app.UseSession();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

В приведенном выше коде:In the preceding code:

  • ПО промежуточного слоя, которое не было добавлено при создании веб-приложения с учетными записями отдельных пользователей, деактивируется.Middleware that is not added when creating a new web app with individual users accounts is commented out.
  • Этот порядок должен соблюдаться не для любого ПО промежуточного слоя.Not every middleware needs to go in this exact order, but many do. Например, определенный порядок должен соблюдаться для UseCors и UseAuthentication.For example, UseCors and UseAuthentication must go in the order shown.

Метод Startup.Configure добавляет компоненты ПО промежуточного слоя для распространенных сценариев приложений:The following Startup.Configure method adds middleware components for common app scenarios:

  1. Обработка исключений/ошибокException/error handling
    • Когда приложение выполняется в среде разработки:When the app runs in the Development environment:
      • ПО промежуточного слоя страницы исключений для разработчика (UseDeveloperExceptionPage) сообщает об ошибках среды выполнения приложения.Developer Exception Page Middleware (UseDeveloperExceptionPage) reports app runtime errors.
      • ПО промежуточного слоя страницы исключений для базы данных (Microsoft.AspNetCore.Builder.DatabaseErrorPageExtensions.UseDatabaseErrorPage) сообщает об ошибках среды выполнения базы данных.Database Error Page Middleware (Microsoft.AspNetCore.Builder.DatabaseErrorPageExtensions.UseDatabaseErrorPage) reports database runtime errors.
    • Когда приложение выполняется в рабочей среде:When the app runs in the Production environment:
      • ПО промежуточного слоя обработчика исключений (UseExceptionHandler) перехватывает исключения, возникшие в указанном ниже ПО промежуточного слоя.Exception Handler Middleware (UseExceptionHandler) catches exceptions thrown in the following middlewares.
      • ПО промежуточного слоя протокола HTTP Strict Transport Security Protocol (HSTS) (UseHsts) добавляет заголовок Strict-Transport-Security.HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) adds the Strict-Transport-Security header.
  2. ПО промежуточного слоя перенаправления HTTPS (UseHttpsRedirection) перенаправляет запросы с HTTP на HTTPS.HTTPS Redirection Middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.
  3. ПО промежуточного слоя статических файлов (UseStaticFiles) возвращает статические файлы и сокращает дальнейшую обработку запросов.Static File Middleware (UseStaticFiles) returns static files and short-circuits further request processing.
  4. ПО промежуточного слоя политики файлов Cookie (UseCookiePolicy) обеспечивает соответствие приложения нормам Общего регламента по защите данных (GDPR) ЕС.Cookie Policy Middleware (UseCookiePolicy) conforms the app to the EU General Data Protection Regulation (GDPR) regulations.
  5. ПО промежуточного слоя проверки подлинности (UseAuthentication) пытается проверить подлинность пользователя, прежде чем предоставить ему доступ к защищенным ресурсам.Authentication Middleware (UseAuthentication) attempts to authenticate the user before they're allowed access to secure resources.
  6. ПО промежуточного слоя сеанса (UseSession) устанавливает и поддерживает состояние сеанса.Session Middleware (UseSession) establishes and maintains session state. Если в приложении используется состояние сеанса, вызовите ПО промежуточного слоя сеанса после ПО промежуточного слоя политики файлов Cookie и до ПО промежуточного слоя MVC.If the app uses session state, call Session Middleware after Cookie Policy Middleware and before MVC Middleware.
  7. ПО промежуточного слоя MVC (UseMvc) добавляет MVC в конвейер запросов.MVC (UseMvc) to add MVC to the request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseAuthentication();
    app.UseSession();
    app.UseMvc();
}

В предыдущем примере кода каждый метод расширения ПО промежуточного слоя представляется в IApplicationBuilder с использованием пространства имен Microsoft.AspNetCore.Builder.In the preceding example code, each middleware extension method is exposed on IApplicationBuilder through the Microsoft.AspNetCore.Builder namespace.

UseExceptionHandler — это первый компонент промежуточного слоя, добавленный в конвейер.UseExceptionHandler is the first middleware component added to the pipeline. Таким образом, обработчик исключений ПО промежуточного слоя перехватывает все исключения, возникающие в последующих вызовах.Therefore, the Exception Handler Middleware catches any exceptions that occur in later calls.

Компонент промежуточного слоя для статических файлов вызывается на раннем этапе конвейера, чтобы он мог обработать запросы и выполнить замыкание, минуя остальные компоненты.Static File Middleware is called early in the pipeline so that it can handle requests and short-circuit without going through the remaining components. Этот компонент не выполняет проверки авторизации.The Static File Middleware provides no authorization checks. Все обрабатываемые им файлы, включая расположенные в wwwroot , находятся в открытом доступе.Any files served by Static File Middleware, including those under wwwroot , are publicly available. Сведения о защите статических файлов см. в статье Статические файлы в ASP.NET Core.For an approach to secure static files, see Статические файлы в ASP.NET Core.

Если запрос не обрабатывается компонентом промежуточного слоя для статических файлов, он передается в компонент промежуточного слоя для проверки подлинности (UseAuthentication), который выполняет проверку подлинности.If the request isn't handled by the Static File Middleware, it's passed on to the Authentication Middleware (UseAuthentication), which performs authentication. Этот компонент не замыкает запросы, не прошедшие проверку подлинности.Authentication doesn't short-circuit unauthenticated requests. Хотя ПО промежуточного слоя для проверки подлинности проверяет подлинность запросов, авторизация (и отклонение) выполняются только после того, как MVC выберет указанную страницу Razor Pages или контроллер MVC и действие.Although Authentication Middleware authenticates requests, authorization (and rejection) occurs only after MVC selects a specific Razor Page or MVC controller and action.

Следующий пример показывает порядок компонентов промежуточного слоя, где запросы для статических файлов обрабатываются компонентом для статических файлов до компонента для сжатия откликов.The following example demonstrates a middleware order where requests for static files are handled by Static File Middleware before Response Compression Middleware. Статические файлы не сжимаются с этим порядком ПО промежуточного слоя.Static files aren't compressed with this middleware order. Отклики MVC из UseMvcWithDefaultRoute можно сжать.The MVC responses from UseMvcWithDefaultRoute can be compressed.

public void Configure(IApplicationBuilder app)
{
    // Static files aren't compressed by Static File Middleware.
    app.UseStaticFiles();

    app.UseResponseCompression();

    app.UseMvcWithDefaultRoute();
}

Методы Use, Run и MapUse, Run, and Map

Для настройки конвейера HTTP служат методы Use, Run и Map.Configure the HTTP pipeline using Use, Run, and Map. Метод Use может замыкать конвейер (это происходит, если он не вызывает делегат запроса next).The Use method can short-circuit the pipeline (that is, if it doesn't call a next request delegate). Run является соглашением, и некоторые компоненты промежуточного слоя могут предоставлять методы Run[Middleware], которые выполняются в конце конвейера.Run is a convention, and some middleware components may expose Run[Middleware] methods that run at the end of the pipeline.

Расширения Map используются в качестве соглашения для ветвления конвейера.Map extensions are used as a convention for branching the pipeline. Map осуществляет ветвление конвейера запросов на основе совпадений для заданного пути запроса.Map branches the request pipeline based on matches of the given request path. Если путь запроса начинается с заданного пути, данная ветвь выполняется.If the request path starts with the given path, the branch is executed.

public class Startup
{
    private static void HandleMapTest1(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 1");
        });
    }

    private static void HandleMapTest2(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 2");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1", HandleMapTest1);

        app.Map("/map2", HandleMapTest2);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}

Ниже приведены запросы и отклики http://localhost:1234 на базе предыдущего кода.The following table shows the requests and responses from http://localhost:1234 using the previous code.

ЗапросRequest ОтветResponse
localhost:1234localhost:1234 Hello from non-Map delegate.Hello from non-Map delegate.
localhost:1234/map1localhost:1234/map1 Map Test 1Map Test 1
localhost:1234/map2localhost:1234/map2 Map Test 2Map Test 2
localhost:1234/map3localhost:1234/map3 Hello from non-Map delegate.Hello from non-Map delegate.

Когда используется Map, соответствующие сегменты путей удаляются из HttpRequest.Path и добавляются к HttpRequest.PathBase для каждого запроса.When Map is used, the matched path segments are removed from HttpRequest.Path and appended to HttpRequest.PathBase for each request.

MapWhen осуществляет ветвление конвейера запросов на основе результата заданного предиката.MapWhen branches the request pipeline based on the result of the given predicate. Любой предикат типа Func<HttpContext, bool> можно использовать для сопоставления запросов с новой ветвью конвейера.Any predicate of type Func<HttpContext, bool> can be used to map requests to a new branch of the pipeline. В следующем примере предикат служит для определения наличия переменной строки запроса branch.In the following example, a predicate is used to detect the presence of a query string variable branch:

public class Startup
{
    private static void HandleBranch(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            var branchVer = context.Request.Query["branch"];
            await context.Response.WriteAsync($"Branch used = {branchVer}");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
                               HandleBranch);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
        });
    }
}

Ниже приведены запросы и отклики http://localhost:1234 на базе предыдущего кода.The following table shows the requests and responses from http://localhost:1234 using the previous code.

ЗапросRequest ОтветResponse
localhost:1234localhost:1234 Hello from non-Map delegate.Hello from non-Map delegate.
localhost:1234/?branch=masterlocalhost:1234/?branch=master Branch used = masterBranch used = master

Map поддерживает вложение, например:Map supports nesting, for example:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map также может сопоставить несколько сегментов одновременно:Map can also match multiple segments at once:

public class Startup
{
    private static void HandleMultiSeg(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map multiple segments.");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1/seg1", HandleMultiSeg);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate.");
        });
    }
}

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

ASP.NET Core содержит следующие компоненты промежуточного слоя.ASP.NET Core ships with the following middleware components. В столбце Порядок указаны сведения о размещении ПО промежуточного слоя в конвейере обработки запросов и условия, в соответствии с которыми ПО промежуточного слоя может прервать обработку запроса.The Order column provides notes on middleware placement in the request processing pipeline and under what conditions the middleware may terminate request processing. Если промежуточный слой замыкает конвейер обработки запроса и препятствует обработке запроса дальнейшими компонентами промежуточного слоя, он называется терминальным промежуточным слоем .When a middleware short-circuits the request processing pipeline and prevents further downstream middleware from processing a request, it's called a terminal middleware . Дополнительные сведения о замыкании конвейера см. в разделе Создание конвейера ПО промежуточного слоя с помощью IApplicationBuilder.For more information on short-circuiting, see the Create a middleware pipeline with IApplicationBuilder section.

ПО промежуточного слояMiddleware ОписаниеDescription НомерOrder
AuthenticationAuthentication Обеспечивает поддержку проверки подлинности.Provides authentication support. Ставится перед тем, как потребуется HttpContext.User.Before HttpContext.User is needed. Является конечным для обратных вызовов OAuth.Terminal for OAuth callbacks.
Политика CookieCookie Policy Позволяет отслеживать согласие пользователей на хранение личных сведений и применять минимальные стандарты для полей файлов cookie, таких как secure и SameSite.Tracks consent from users for storing personal information and enforces minimum standards for cookie fields, such as secure and SameSite. Перед ПО промежуточного слоя, которое использует файлы cookie.Before middleware that issues cookies. Примеры Authentication, Session, MVC (TempData).Examples: Authentication, Session, MVC (TempData).
CORSCORS Настраивает общий доступ к ресурсам независимо от источника.Configures Cross-Origin Resource Sharing. Ставится перед компонентами, использующими CORS.Before components that use CORS.
Error HandlingDiagnostics Отдельное ПО промежуточного слоя, которое обеспечивает обработку исключений, предоставляет страницу исключений для разработчика, страницы состояния кода, веб-страницу по умолчанию для новых приложений.Several separate middlewares that provide a developer exception page, exception handling, status code pages, and the default web page for new apps. Ставится перед компонентами, выдающими ошибки.Before components that generate errors. Является конечным для исключений или обслуживания веб-страницы по умолчанию для новых приложений.Terminal for exceptions or serving the default web page for new apps.
Forwarded HeadersForwarded Headers Пересылает заголовки, переданные через прокси-сервер, в текущий запрос.Forwards proxied headers onto the current request. Перед компонентами, использующими обновленные поля.Before components that consume the updated fields. Например: схема, узел, IP-адрес клиента, метод.Examples: scheme, host, client IP, method.
Проверка работоспособностиHealth Check Проверяет работоспособность приложения ASP.NET Core и его зависимостей, таких как проверка доступности базы данных.Checks the health of an ASP.NET Core app and its dependencies, such as checking database availability. Является конечным, если запрос соответствует конечной точке проверки работоспособности.Terminal if a request matches a health check endpoint.
HTTP Method OverrideHTTP Method Override Разрешает входящий запрос POST для переопределения этого метода.Allows an incoming POST request to override the method. Ставится перед компонентами, использующими обновленный метод.Before components that consume the updated method.
HTTPS RedirectionHTTPS Redirection Перенаправляет все запросы HTTP на HTTPS.Redirect all HTTP requests to HTTPS. Ставится перед компонентами, использующими URL-адрес.Before components that consume the URL.
HTTP Strict Transport Security (HSTS)HTTP Strict Transport Security (HSTS) ПО промежуточного слоя для повышения безопасности, которое добавляет специальный заголовок ответа.Security enhancement middleware that adds a special response header. Перед отправкой ответов и после компонентов, изменяющих запросы.Before responses are sent and after components that modify requests. Примеры Forwarded Headers, URL Rewriting.Examples: Forwarded Headers, URL Rewriting.
MVCMVC Обрабатывает запросы с помощью MVC либо Razor Pages.Processes requests with MVC/Razor Pages. Является конечным, если запрос соответствует маршруту.Terminal if a request matches a route.
OWINOWIN Взаимодействие с приложениями, серверами и ПО промежуточного слоя на основе OWIN.Interop with OWIN-based apps, servers, and middleware. Является конечным, если ПО промежуточного слоя OWIN полностью обрабатывает запрос.Terminal if the OWIN Middleware fully processes the request.
Кэширование ответовResponse Caching Обеспечивает поддержку для кэширования откликов.Provides support for caching responses. Ставится перед компонентами, требующими кэширование.Before components that require caching.
Сжатие откликовResponse Compression Обеспечивает поддержку для сжатия откликов.Provides support for compressing responses. Ставится перед компонентами, требующими сжатие.Before components that require compression.
LocalizationRequest Localization Обеспечивает поддержку локализации.Provides localization support. Ставится перед компонентами, для которых важна локализация.Before localization sensitive components.
Маршрутизация конечных точекEndpoint Routing Определяет и ограничивает маршруты запросов.Defines and constrains request routes. Является конечным для совпадающих маршрутов.Terminal for matching routes.
SessionSession Обеспечивает поддержку для управления пользовательскими сеансами.Provides support for managing user sessions. Ставится перед компонентами, требующими сеанс.Before components that require Session.
Static FilesStatic Files Обеспечивает поддержку для обработки статических файлов и просмотра каталогов.Provides support for serving static files and directory browsing. Является конечным, если запрос соответствует файлу.Terminal if a request matches a file.
Переопределение URL-адресовURL Rewrite Обеспечивает поддержку для переопределения URL-адресов и перенаправления запросов.Provides support for rewriting URLs and redirecting requests. Ставится перед компонентами, использующими URL-адрес.Before components that consume the URL.
WebSocketsWebSockets Обеспечивает поддержку протокола WebSockets.Enables the WebSockets protocol. Ставится перед компонентами, которым нужно принимать запросы WebSocket.Before components that are required to accept WebSocket requests.

Дополнительные ресурсыAdditional resources