Middleware de ASP.NET CoreASP.NET Core Middleware

Por Rick Anderson y Steve SmithBy Rick Anderson and Steve Smith

El software intermedio es un software que se ensambla en una canalización de una aplicación para controlar las solicitudes y las respuestas.Middleware is software that's assembled into an app pipeline to handle requests and responses. Cada componente puede hacer lo siguiente:Each component:

  • Elegir si se pasa la solicitud al siguiente componente de la canalización.Chooses whether to pass the request to the next component in the pipeline.
  • Realizar trabajos antes y después del siguiente componente de la canalización.Can perform work before and after the next component in the pipeline.

Los delegados de solicitudes se usan para crear la canalización de solicitudes.Request delegates are used to build the request pipeline. Estos también controlan las solicitudes HTTP.The request delegates handle each HTTP request.

Los delegados de solicitudes se configuran con los métodos de extensión Run, Map y Use.Request delegates are configured using Run, Map, and Use extension methods. Un delegado de solicitudes se puede especificar en línea como un método anónimo (denominado middleware en línea) o se puede definir en una clase reutilizable.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. Estas clases reutilizables y métodos anónimos en línea se conocen como software intermedio o componentes de software intermedio.These reusable classes and in-line anonymous methods are middleware, also called middleware components. Cada componente de software intermedio de la canalización de solicitudes es responsable de invocar el siguiente componente de la canalización o de cortocircuitar la canalización, en caso de ser necesario.Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the pipeline. Cuando un middleware se cortocircuita, se llama middleware de terminal porque impide el procesamiento de la solicitud por parte de middleware adicional.When a middleware short-circuits, it's called a terminal middleware because it prevents further middleware from processing the request.

En Migración de controladores y módulos HTTP a middleware de ASP.NET Core se explica la diferencia entre las canalizaciones de solicitudes en ASP.NET Core y ASP.NET 4.x y se proporcionan ejemplos adicionales de middleware.Migración de controladores y módulos HTTP a middleware de ASP.NET Core explains the difference between request pipelines in ASP.NET Core and ASP.NET 4.x and provides additional middleware samples.

Creación de una canalización de software intermedio con IApplicationBuilderCreate a middleware pipeline with IApplicationBuilder

La canalización de solicitudes de ASP.NET Core consiste en una secuencia de delegados de solicitud a los que se llama de uno en uno.The ASP.NET Core request pipeline consists of a sequence of request delegates, called one after the other. En el siguiente diagrama se muestra este concepto.The following diagram demonstrates the concept. El subproceso de ejecución sigue las flechas negras.The thread of execution follows the black arrows.

En el patrón de procesamiento de solicitudes se muestra una solicitud entrante, el procesamiento a través de tres softwares intermedios y la respuesta saliente de la aplicación.

Cada delegado puede realizar operaciones antes y después del siguiente.Each delegate can perform operations before and after the next delegate. Los delegados que controlan excepciones deben llamarse al principio de la canalización para que puedan capturar las excepciones que se producen en las fases siguientes de la canalización.Exception-handling delegates should be called early in the pipeline, so they can catch exceptions that occur in later stages of the pipeline.

La aplicación ASP.NET Core más sencilla posible configura un solo delegado de solicitudes que controla todas las solicitudes.The simplest possible ASP.NET Core app sets up a single request delegate that handles all requests. En este caso no se incluye una canalización de solicitudes real.This case doesn't include an actual request pipeline. En su lugar, solo se llama a una única función anónima en respuesta a todas las solicitudes 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!");
        });
    }
}

Encadene varios delegados de solicitudes con Use.Chain multiple request delegates together with Use. El parámetro next representa el siguiente delegado de la canalización.The next parameter represents the next delegate in the pipeline. Si no llama al siguiente parámetro, puede cortocircuitar la canalización.You can short-circuit the pipeline by not calling the next parameter. Normalmente, puede realizar acciones antes y después del siguiente delegado, tal como se muestra en el ejemplo siguiente: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.");
        });
    }
}

Cuando un delegado no pasa una solicitud al siguiente delegado, se denomina cortocircuitar la canalización de solicitudes.When a delegate doesn't pass a request to the next delegate, it's called short-circuiting the request pipeline. Este proceso es necesario muchas veces, ya que previene la realización de trabajo innecesario.Short-circuiting is often desirable because it avoids unnecessary work. Por ejemplo, el middleware de archivos estáticos puede actuar como middleware de terminal procesando una solicitud para un archivo estático y cortocircuitando el resto de la canalización.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. El middleware agregado a la canalización antes del middleware que finaliza el procesamiento sigue procesando código después de sus instrucciones next.Invoke.Middleware added to the pipeline before the middleware that terminates further processing still processes code after their next.Invoke statements. Sin embargo, consulte la siguiente advertencia sobre intentar escribir en una respuesta que ya se ha enviado.However, see the following warning about attempting to write to a response that has already been sent.

Advertencia

No llame a next.Invoke después de haber enviado la respuesta al cliente.Don't call next.Invoke after the response has been sent to the client. Si se modifica HttpResponse después de haber iniciado la respuesta, se producirá una excepción.Changes to HttpResponse after the response has started throw an exception. Por ejemplo, se producirá una excepción al realizar cambios tales como el establecimiento de encabezados o el código.For example, changes such as setting headers and a status code throw an exception. Si escribe en el cuerpo de la respuesta después de llamar a next:Writing to the response body after calling next:

  • Puede provocar una infracción del protocolo.May cause a protocol violation. Por ejemplo, si escribe más de la longitud Content-Length establecida.For example, writing more than the stated Content-Length.
  • Puede dañar el formato del cuerpo.May corrupt the body format. Por ejemplo, si escribe un pie de página en HTML en un archivo CSS.For example, writing an HTML footer to a CSS file.

HasStarted es una sugerencia útil para indicar si se han enviado los encabezados o se han realizado escrituras en el cuerpo.HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.

Los delegados de Run no reciben un parámetro next.Run delegates don't receive a next parameter. El primer delegado de Run siempre es terminal y finaliza la canalización.The first Run delegate is always terminal and terminates the pipeline. Run es una convención.Run is a convention. Es posible que algunos componentes de middleware expongan métodos Run[Middleware] que se ejecutan al final de la canalización: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.");
        });
    }
}

Si quiere que los comentarios de código se traduzcan en más idiomas además del inglés, háganoslo saber en este problema de debate de GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

En el ejemplo anterior, el delegado Run escribe "Hello from 2nd delegate." en la respuesta y, después, termina la canalización.In the preceding example, the Run delegate writes "Hello from 2nd delegate." to the response and then terminates the pipeline. Si se agrega otro delegado Use o Run después de Run, no se le llama.If another Use or Run delegate is added after the Run delegate, it's not called.

Orden del middlewareMiddleware order

En el diagrama siguiente se muestra la canalización de procesamiento de solicitudes completa para las aplicaciones de ASP.NET Core MVC y de Razor Pages.The following diagram shows the complete request processing pipeline for ASP.NET Core MVC and Razor Pages apps. Puede ver cómo, en una aplicación típica, se ordenan los middleware existentes y dónde se agregan los middleware personalizados.You can see how, in a typical app, existing middlewares are ordered and where custom middlewares are added. Tiene control total sobre cómo reordenar los middleware existentes o insertar nuevos middleware personalizados según sea necesario para sus escenarios.You have full control over how to reorder existing middlewares or inject new custom middlewares as necessary for your scenarios.

Canalización de middleware de ASP.NET Core

El middleware Punto de conexión del diagrama anterior ejecuta la canalización de filtro para el tipo de aplicación correspondiente—MVC o Razor Pages.The Endpoint middleware in the preceding diagram executes the filter pipeline for the corresponding app type—MVC or Razor Pages.

Canalización de filtro de ASP.NET Core

El orden en el que se agregan los componentes de software intermedio en el método Startup.Configure define el orden en el que se invocarán los componentes de software intermedio en las solicitudes y el orden inverso de la respuesta.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. Por motivos de seguridad, rendimiento y funcionalidad, el orden es crítico.The order is critical for security, performance, and functionality.

El método Startup.Configure siguiente agrega componentes de middleware relacionados con la seguridad en el orden recomendado: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.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

En el código anterior:In the preceding code:

  • El middleware que no se agrega al crear una aplicación web con cuentas de usuario individuales se convierte en comentario.Middleware that is not added when creating a new web app with individual users accounts is commented out.
  • No todo el middleware tiene que ir en este orden exacto, pero gran parte sí lo hace.Not every middleware needs to go in this exact order, but many do. Por ejemplo, UseCors, UseAuthentication y UseAuthorization deben ir en el orden mostrado.For example, UseCors, UseAuthentication, and UseAuthorization must go in the order shown.

El siguiente método Startup.Configure agrega los componentes de middleware para escenarios de aplicaciones comunes:The following Startup.Configure method adds middleware components for common app scenarios:

  1. Control de errores y excepcionesException/error handling
    • Cuando la aplicación se ejecuta en el entorno de desarrollo:When the app runs in the Development environment:
      • El middleware de la página de excepciones para el desarrollador (UseDeveloperExceptionPage) informa los errores en tiempo de ejecución de la aplicación.Developer Exception Page Middleware (UseDeveloperExceptionPage) reports app runtime errors.
      • El middleware de la página de errores de la base de datos informa de los errores en tiempo de ejecución de la base de datos.Database Error Page Middleware reports database runtime errors.
    • Cuando la aplicación se ejecuta en el entorno de producción:When the app runs in the Production environment:
      • El middleware del controlador de excepciones (UseExceptionHandler) detecta las excepciones generadas en los middlewares siguientes.Exception Handler Middleware (UseExceptionHandler) catches exceptions thrown in the following middlewares.
      • El middleware del protocolo de seguridad de transporte estricta de HTTP (HSTS) (UseHsts) agrega el encabezado Strict-Transport-Security.HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) adds the Strict-Transport-Security header.
  2. El middleware de redireccionamiento de HTTPS (UseHttpsRedirection) redirige las solicitudes HTTP a HTTPS.HTTPS Redirection Middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.
  3. El middleware de archivos estáticos (UseStaticFiles) devuelve archivos estáticos y genera un cortocircuito más allá del procesamiento de la solicitud.Static File Middleware (UseStaticFiles) returns static files and short-circuits further request processing.
  4. El middleware de directivas de cookies (UseCookiePolicy) permite que la aplicación cumpla con las normas del Reglamento general de protección de datos (RGPD) de la Unión Europea.Cookie Policy Middleware (UseCookiePolicy) conforms the app to the EU General Data Protection Regulation (GDPR) regulations.
  5. Middleware de enrutamiento (UseRouting) para enrutar las solicitudes.Routing Middleware (UseRouting) to route requests.
  6. El middleware de autenticación (UseAuthentication) intenta autenticar al usuarios antes de que se le permita acceder a los recursos protegidos.Authentication Middleware (UseAuthentication) attempts to authenticate the user before they're allowed access to secure resources.
  7. El middleware de autorización (UseAuthorization) autoriza a los usuarios a acceder a los recursos seguros.Authorization Middleware (UseAuthorization) authorizes a user to access secure resources.
  8. El middleware de sesiones (UseSession) establece y mantiene el estado de sesión.Session Middleware (UseSession) establishes and maintains session state. Si la aplicación usa el estado de sesión, llame al middleware de sesiones después del middleware de directivas de cookies y antes del middleware de MVC.If the app uses session state, call Session Middleware after Cookie Policy Middleware and before MVC Middleware.
  9. Middleware de enrutamiento de punto de conexión (UseEndpoints con MapRazorPages) para agregar puntos de conexión de Razor Pages a la canalización de solicitudes.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();
    });
}

En el código de ejemplo anterior, cada método de extensión de software intermedio se expone en IApplicationBuilder a través del espacio de nombres de Microsoft.AspNetCore.Builder.In the preceding example code, each middleware extension method is exposed on IApplicationBuilder through the Microsoft.AspNetCore.Builder namespace.

UseExceptionHandler es el primer componente de software intermedio que se agrega a la canalización.UseExceptionHandler is the first middleware component added to the pipeline. Por lo tanto, el software intermedio del controlador de excepciones detectará las excepciones que se produzcan en las llamadas posteriores.Therefore, the Exception Handler Middleware catches any exceptions that occur in later calls.

El software intermedio de archivos estáticos se llama al principio de la canalización para que pueda controlar solicitudes y realizar cortocircuitos sin pasar por los componentes restantes.Static File Middleware is called early in the pipeline so that it can handle requests and short-circuit without going through the remaining components. Este middleware no proporciona comprobaciones de autorización.The Static File Middleware provides no authorization checks. Los archivos que proporciona el middleware de archivos estáticos, incluidos los de wwwroot, están disponibles de forma pública.Any files served by Static File Middleware, including those under wwwroot, are publicly available. Para obtener más información sobre cómo proteger este tipo de archivos, vea Archivos estáticos en ASP.NET Core.For an approach to secure static files, see Archivos estáticos en ASP.NET Core.

Si el software intermedio de archivos estáticos no controla la solicitud, se pasará al software intermedio de autenticación (UseAuthentication), que realizará la autenticación.If the request isn't handled by the Static File Middleware, it's passed on to the Authentication Middleware (UseAuthentication), which performs authentication. Este software intermedio no cortocircuita las solicitudes sin autenticación.Authentication doesn't short-circuit unauthenticated requests. Aunque autentique solicitudes, la autorización (y también el rechazo) se producirán después de que MVC seleccione una página de Razor o un control y una acción de MVC concretos.Although Authentication Middleware authenticates requests, authorization (and rejection) occurs only after MVC selects a specific Razor Page or MVC controller and action.

En el ejemplo siguiente se muestra un orden de software intermedio en el que el software intermedio de archivos estáticos controla las solicitudes de archivos estáticos antes del software intermedio de compresión de respuestas.The following example demonstrates a middleware order where requests for static files are handled by Static File Middleware before Response Compression Middleware. Los archivos estáticos no se comprimen en este orden de software intermedio.Static files aren't compressed with this middleware order. Las respuestas de Razor Pages se pueden comprimir.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();
    });
}

En el caso de las aplicaciones de página única (SPA), el middleware de SPA UseSpaStaticFiles normalmente se incluye en último lugar en la canalización de middleware.For Single Page Applications (SPAs), the SPA middleware UseSpaStaticFiles usually comes last in the middleware pipeline. El middleware de SPA se incluye en último lugar:The SPA middleware comes last:

  • Para permitir que todos los demás middleware respondan a las solicitudes coincidentes primero.To allow all other middlewares to respond to matching requests first.
  • Para permitir que SPA con enrutamiento del lado cliente se ejecuten para todas las rutas que no reconoce la aplicación de servidor.To allow SPAs with client-side routing to run for all routes that are unrecognized by the server app.

Para obtener más información sobre las SPA, consulte las guías de las plantillas de proyecto React y Angular.For more details on SPAs, see the guides for the React and Angular project templates.

Creación de una rama de la canalización de middlewareBranch the middleware pipeline

Las extensiones Map se usan como convenciones para la creación de ramas en la canalización.Map extensions are used as a convention for branching the pipeline. Map crea una rama de la canalización de solicitudes según las coincidencias de la ruta de solicitud proporcionada.Map branches the request pipeline based on matches of the given request path. Si la ruta de solicitud comienza con la ruta proporcionada, se ejecuta la creación de la rama.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>");
        });
    }
}

En la siguiente tabla se muestran las solicitudes y las respuestas de http://localhost:1234 con el código anterior.The following table shows the requests and responses from http://localhost:1234 using the previous code.

RequestRequest RespuestaResponse
localhost:1234localhost:1234 Saludos del delegado sin Map.Hello from non-Map delegate.
localhost:1234/map1localhost:1234/map1 Prueba 1 de MapMap Test 1
localhost:1234/map2localhost:1234/map2 Prueba 2 de MapMap Test 2
localhost:1234/map3localhost:1234/map3 Saludos del delegado sin Map.Hello from non-Map delegate.

Cuando se usa Map, los segmentos de ruta que coincidan se eliminan de HttpRequest.Path y se anexan a HttpRequest.PathBase para cada solicitud.When Map is used, the matched path segments are removed from HttpRequest.Path and appended to HttpRequest.PathBase for each request.

Map admite la anidación, por ejemplo:Map supports nesting, for example:

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

Map puede hacer coincidir varios segmentos a la vez: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 crea una rama de la canalización de solicitudes según el resultado del predicado proporcionado.MapWhen branches the request pipeline based on the result of the given predicate. Se puede usar cualquier predicado de tipo Func<HttpContext, bool> para asignar solicitudes a nuevas ramas de la canalización.Any predicate of type Func<HttpContext, bool> can be used to map requests to a new branch of the pipeline. En el ejemplo siguiente se usa un predicado para detectar la presencia de una branch variable de cadena de consulta: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>");
        });
    }
}

En la siguiente tabla se muestran las solicitudes y las respuestas de http://localhost:1234 con el código anterior:The following table shows the requests and responses from http://localhost:1234 using the previous code:

RequestRequest RespuestaResponse
localhost:1234localhost:1234 Saludos del delegado sin Map.Hello from non-Map delegate.
localhost:1234/?branch=masterlocalhost:1234/?branch=master Rama usada = masterBranch used = master

UseWhen también crea una rama de la canalización de solicitudes según el resultado del predicado proporcionado.UseWhen also branches the request pipeline based on the result of the given predicate. A diferencia de lo que sucede con MapWhen, esta rama se vuelve a unir a la canalización principal si no realiza un cortocircuito ni contiene un middleware de terminal: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 readonly ILogger<Startup> _logger;

    public Startup(ILogger<Startup> logger)
    {
        _logger = logger;
    }

    private void HandleBranchAndRejoin(IApplicationBuilder app)
    {
        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)
    {
        app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
                               HandleBranchAndRejoin);

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

En el ejemplo anterior, la respuesta "Hola desde la canalización principal."In the preceding example, a response of "Hello from main pipeline." se escribe para todas las solicitudes.is written for all requests. Si la solicitud incluye una variable de cadena de consulta branch, su valor se registra antes de que se vuelva a unir la canalización principal.If the request includes a query string variable branch, its value is logged before the main pipeline is rejoined.

Middleware integradoBuilt-in middleware

ASP.NET Core incluye los componentes de software intermedio siguientes.ASP.NET Core ships with the following middleware components. En la columna Orden se proporcionan notas sobre la ubicación del middleware en la canalización de procesamiento de solicitudes, así como las condiciones con las que podría finalizar el procesamiento de solicitudes.The Order column provides notes on middleware placement in the request processing pipeline and under what conditions the middleware may terminate request processing. Cuando un middleware cortocircuita la canalización de procesamiento de solicitudes e impide el procesamiento de una solicitud por parte de middleware descendente adicional, se llama middleware de terminal.When a middleware short-circuits the request processing pipeline and prevents further downstream middleware from processing a request, it's called a terminal middleware. Para más información sobre cómo cortocircuitar, consulte la sección Creación de una canalización de middleware con IApplicationBuilder.For more information on short-circuiting, see the Create a middleware pipeline with IApplicationBuilder section.

Software intermedioMiddleware DescripciónDescription OrdenarOrder
AutenticaciónAuthentication Proporciona compatibilidad con autenticación.Provides authentication support. Antes de que se necesite HttpContext.User.Before HttpContext.User is needed. Terminal para devoluciones de llamadas OAuth.Terminal for OAuth callbacks.
AutorizaciónAuthorization Proporciona compatibilidad con la autorización.Provides authorization support. Inmediatamente después del middleware de autenticación.Immediately after the Authentication Middleware.
Directiva de cookiesCookie Policy Realiza un seguimiento del consentimiento de los usuarios para almacenar información personal y aplica los estándares mínimos para los campos de las cookies, como secure y SameSite.Tracks consent from users for storing personal information and enforces minimum standards for cookie fields, such as secure and SameSite. Antes del middleware que emite las cookies.Before middleware that issues cookies. Ejemplos: autenticación, sesión y MVC (TempData).Examples: Authentication, Session, MVC (TempData).
CORSCORS Configura el uso compartido de recursos entre orígenes.Configures Cross-Origin Resource Sharing. Antes de los componentes que usan CORS.Before components that use CORS.
DiagnósticoDiagnostics Varios middleware independientes que proporcionan una página de excepciones para el desarrollador, control de excepciones, páginas de códigos de estado y la página web predeterminada para las nuevas aplicaciones.Several separate middlewares that provide a developer exception page, exception handling, status code pages, and the default web page for new apps. Antes de los componentes que generan errores.Before components that generate errors. Terminal para excepciones o con el fin de proporcionar la página web predeterminada para las nuevas aplicaciones.Terminal for exceptions or serving the default web page for new apps.
Encabezados reenviadosForwarded Headers Reenvía encabezados con proxy a la solicitud actual.Forwards proxied headers onto the current request. Antes de los componentes que consumen los campos actualizados.Before components that consume the updated fields. Ejemplos: esquema, host, IP de cliente y método.Examples: scheme, host, client IP, method.
Comprobación de estadoHealth Check Comprueba el estado de una aplicación ASP.NET Core y sus dependencias, como la comprobación de disponibilidad de base de datos.Checks the health of an ASP.NET Core app and its dependencies, such as checking database availability. Terminal si una solicitud coincide con un punto de conexión de comprobación de estado.Terminal if a request matches a health check endpoint.
Propagación de encabezadosHeader Propagation Permite propagar los encabezados HTTP de la solicitud entrante a las solicitudes del cliente HTTP salientes.Propagates HTTP headers from the incoming request to the outgoing HTTP Client requests.
Invalidación del método HTTPHTTP Method Override Permite que una solicitud POST entrante invalide el método.Allows an incoming POST request to override the method. Antes de los componentes que consumen el método actualizado.Before components that consume the updated method.
Redireccionamiento de HTTPSHTTPS Redirection Redirija todas las solicitudes HTTP a HTTPS.Redirect all HTTP requests to HTTPS. Antes de los componentes que consumen la dirección URL.Before components that consume the URL.
Seguridad de transporte estricta de HTTP (HSTS)HTTP Strict Transport Security (HSTS) Middleware de mejora de seguridad que agrega un encabezado de respuesta especial.Security enhancement middleware that adds a special response header. Antes de que se envíen las respuestas y después de los componentes que modifican las solicitudes.Before responses are sent and after components that modify requests. Ejemplos: encabezados reenviados y reescritura de URL.Examples: Forwarded Headers, URL Rewriting.
MVCMVC Procesa las solicitudes con MVC/Razor Pages.Processes requests with MVC/Razor Pages. Si hay una solicitud que coincida con una ruta, será final.Terminal if a request matches a route.
OWINOWIN Puede interoperar con aplicaciones, servidores y software intermedio basados en OWIN.Interop with OWIN-based apps, servers, and middleware. Si el software intermedio de OWIN procesa completamente la solicitud, será final.Terminal if the OWIN Middleware fully processes the request.
Almacenamiento en caché de respuestasResponse Caching Proporciona compatibilidad con la captura de respuestas.Provides support for caching responses. Antes de los componentes que requieren el almacenamiento en caché.Before components that require caching.
Compresión de respuestaResponse Compression Proporciona compatibilidad con la compresión de respuestas.Provides support for compressing responses. Antes de los componentes que requieren compresión.Before components that require compression.
Localización de solicitudesRequest Localization Proporciona compatibilidad con ubicación.Provides localization support. Antes de los componentes que dependen de la ubicación.Before localization sensitive components.
Enrutamiento de punto de conexiónEndpoint Routing Define y restringe las rutas de la solicitud.Defines and constrains request routes. Terminal para rutas que coincidan.Terminal for matching routes.
SPASPA Controla todas las solicitudes desde este punto de la cadena de middleware devolviendo la página predeterminada de la aplicación de página única (SPA).Handles all requests from this point in the middleware chain by returning the default page for the Single Page Application (SPA) En un punto posterior de la cadena, de modo que otro middleware dedicado a proporcionar archivos estáticos, acciones de MVC y otros elementos tenga prioridad.Late in the chain, so that other middleware for serving static files, MVC actions, etc., takes precedence.
SesiónSession Proporciona compatibilidad con la administración de sesiones de usuario.Provides support for managing user sessions. Antes de los componentes que requieren Session.Before components that require Session.
Archivos estáticosStatic Files Proporciona compatibilidad con la proporción de archivos estáticos y la exploración de directorios.Provides support for serving static files and directory browsing. Si hay una solicitud que coincida con un archivo, será final.Terminal if a request matches a file.
Reescritura de URLURL Rewrite Proporciona compatibilidad con la reescritura de direcciones URL y la redirección de solicitudes.Provides support for rewriting URLs and redirecting requests. Antes de los componentes que consumen la dirección URL.Before components that consume the URL.
WebSocketsWebSockets Habilita el protocolo WebSockets.Enables the WebSockets protocol. Antes de los componentes necesarios para aceptar solicitudes de WebSocket.Before components that are required to accept WebSocket requests.

Recursos adicionalesAdditional resources

Por Rick Anderson y Steve SmithBy Rick Anderson and Steve Smith

El software intermedio es un software que se ensambla en una canalización de una aplicación para controlar las solicitudes y las respuestas.Middleware is software that's assembled into an app pipeline to handle requests and responses. Cada componente puede hacer lo siguiente:Each component:

  • Elegir si se pasa la solicitud al siguiente componente de la canalización.Chooses whether to pass the request to the next component in the pipeline.
  • Realizar trabajos antes y después del siguiente componente de la canalización.Can perform work before and after the next component in the pipeline.

Los delegados de solicitudes se usan para crear la canalización de solicitudes.Request delegates are used to build the request pipeline. Estos también controlan las solicitudes HTTP.The request delegates handle each HTTP request.

Los delegados de solicitudes se configuran con los métodos de extensión Run, Map y Use.Request delegates are configured using Run, Map, and Use extension methods. Un delegado de solicitudes se puede especificar en línea como un método anónimo (denominado middleware en línea) o se puede definir en una clase reutilizable.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. Estas clases reutilizables y métodos anónimos en línea se conocen como software intermedio o componentes de software intermedio.These reusable classes and in-line anonymous methods are middleware, also called middleware components. Cada componente de software intermedio de la canalización de solicitudes es responsable de invocar el siguiente componente de la canalización o de cortocircuitar la canalización, en caso de ser necesario.Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the pipeline. Cuando un middleware se cortocircuita, se llama middleware de terminal porque impide el procesamiento de la solicitud por parte de middleware adicional.When a middleware short-circuits, it's called a terminal middleware because it prevents further middleware from processing the request.

En Migración de controladores y módulos HTTP a middleware de ASP.NET Core se explica la diferencia entre las canalizaciones de solicitudes en ASP.NET Core y ASP.NET 4.x y se proporcionan ejemplos adicionales de middleware.Migración de controladores y módulos HTTP a middleware de ASP.NET Core explains the difference between request pipelines in ASP.NET Core and ASP.NET 4.x and provides additional middleware samples.

Creación de una canalización de software intermedio con IApplicationBuilderCreate a middleware pipeline with IApplicationBuilder

La canalización de solicitudes de ASP.NET Core consiste en una secuencia de delegados de solicitud a los que se llama de uno en uno.The ASP.NET Core request pipeline consists of a sequence of request delegates, called one after the other. En el siguiente diagrama se muestra este concepto.The following diagram demonstrates the concept. El subproceso de ejecución sigue las flechas negras.The thread of execution follows the black arrows.

En el patrón de procesamiento de solicitudes se muestra una solicitud entrante, el procesamiento a través de tres softwares intermedios y la respuesta saliente de la aplicación.

Cada delegado puede realizar operaciones antes y después del siguiente.Each delegate can perform operations before and after the next delegate. Los delegados que controlan excepciones deben llamarse al principio de la canalización para que puedan capturar las excepciones que se producen en las fases siguientes de la canalización.Exception-handling delegates should be called early in the pipeline, so they can catch exceptions that occur in later stages of the pipeline.

La aplicación ASP.NET Core más sencilla posible configura un solo delegado de solicitudes que controla todas las solicitudes.The simplest possible ASP.NET Core app sets up a single request delegate that handles all requests. En este caso no se incluye una canalización de solicitudes real.This case doesn't include an actual request pipeline. En su lugar, solo se llama a una única función anónima en respuesta a todas las solicitudes 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!");
        });
    }
}

El primer delegado de Run finaliza la canalización.The first Run delegate terminates the pipeline.

Encadene varios delegados de solicitudes con Use.Chain multiple request delegates together with Use. El parámetro next representa el siguiente delegado de la canalización.The next parameter represents the next delegate in the pipeline. Si no llama al siguiente parámetro, puede cortocircuitar la canalización.You can short-circuit the pipeline by not calling the next parameter. Normalmente, puede realizar acciones antes y después del siguiente delegado, tal como se muestra en el ejemplo siguiente: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.");
        });
    }
}

Cuando un delegado no pasa una solicitud al siguiente delegado, se denomina cortocircuitar la canalización de solicitudes.When a delegate doesn't pass a request to the next delegate, it's called short-circuiting the request pipeline. Este proceso es necesario muchas veces, ya que previene la realización de trabajo innecesario.Short-circuiting is often desirable because it avoids unnecessary work. Por ejemplo, el middleware de archivos estáticos puede actuar como middleware de terminal procesando una solicitud para un archivo estático y cortocircuitando el resto de la canalización.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. El middleware agregado a la canalización antes del middleware que finaliza el procesamiento sigue procesando código después de sus instrucciones next.Invoke.Middleware added to the pipeline before the middleware that terminates further processing still processes code after their next.Invoke statements. Sin embargo, consulte la siguiente advertencia sobre intentar escribir en una respuesta que ya se ha enviado.However, see the following warning about attempting to write to a response that has already been sent.

Advertencia

No llame a next.Invoke después de haber enviado la respuesta al cliente.Don't call next.Invoke after the response has been sent to the client. Si se modifica HttpResponse después de haber iniciado la respuesta, se producirá una excepción.Changes to HttpResponse after the response has started throw an exception. Por ejemplo, se producirá una excepción al realizar cambios tales como el establecimiento de encabezados o el código.For example, changes such as setting headers and a status code throw an exception. Si escribe en el cuerpo de la respuesta después de llamar a next:Writing to the response body after calling next:

  • Puede provocar una infracción del protocolo.May cause a protocol violation. Por ejemplo, si escribe más de la longitud Content-Length establecida.For example, writing more than the stated Content-Length.
  • Puede dañar el formato del cuerpo.May corrupt the body format. Por ejemplo, si escribe un pie de página en HTML en un archivo CSS.For example, writing an HTML footer to a CSS file.

HasStarted es una sugerencia útil para indicar si se han enviado los encabezados o se han realizado escrituras en el cuerpo.HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.

Orden del middlewareMiddleware order

El orden en el que se agregan los componentes de software intermedio en el método Startup.Configure define el orden en el que se invocarán los componentes de software intermedio en las solicitudes y el orden inverso de la respuesta.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. Por motivos de seguridad, rendimiento y funcionalidad, el orden es crítico.The order is critical for security, performance, and functionality.

El método Startup.Configure siguiente agrega componentes de middleware relacionados con la seguridad en el orden recomendado: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?}");
    });
}

En el código anterior:In the preceding code:

  • El middleware que no se agrega al crear una aplicación web con cuentas de usuario individuales se convierte en comentario.Middleware that is not added when creating a new web app with individual users accounts is commented out.
  • No todo el middleware tiene que ir en este orden exacto, pero gran parte sí lo hace.Not every middleware needs to go in this exact order, but many do. Por ejemplo, UseCors y UseAuthentication deben ir en el orden mostrado.For example, UseCors and UseAuthentication must go in the order shown.

El siguiente método Startup.Configure agrega los componentes de middleware para escenarios de aplicaciones comunes:The following Startup.Configure method adds middleware components for common app scenarios:

  1. Control de errores y excepcionesException/error handling
    • Cuando la aplicación se ejecuta en el entorno de desarrollo:When the app runs in the Development environment:
      • El middleware de la página de excepciones para el desarrollador (UseDeveloperExceptionPage) informa los errores en tiempo de ejecución de la aplicación.Developer Exception Page Middleware (UseDeveloperExceptionPage) reports app runtime errors.
      • El middleware de la página de errores de la base de datos (Microsoft.AspNetCore.Builder.DatabaseErrorPageExtensions.UseDatabaseErrorPage) informa los errores en tiempo de ejecución de la base de datos.Database Error Page Middleware (Microsoft.AspNetCore.Builder.DatabaseErrorPageExtensions.UseDatabaseErrorPage) reports database runtime errors.
    • Cuando la aplicación se ejecuta en el entorno de producción:When the app runs in the Production environment:
      • El middleware del controlador de excepciones (UseExceptionHandler) detecta las excepciones generadas en los middlewares siguientes.Exception Handler Middleware (UseExceptionHandler) catches exceptions thrown in the following middlewares.
      • El middleware del protocolo de seguridad de transporte estricta de HTTP (HSTS) (UseHsts) agrega el encabezado Strict-Transport-Security.HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) adds the Strict-Transport-Security header.
  2. El middleware de redireccionamiento de HTTPS (UseHttpsRedirection) redirige las solicitudes HTTP a HTTPS.HTTPS Redirection Middleware (UseHttpsRedirection) redirects HTTP requests to HTTPS.
  3. El middleware de archivos estáticos (UseStaticFiles) devuelve archivos estáticos y genera un cortocircuito más allá del procesamiento de la solicitud.Static File Middleware (UseStaticFiles) returns static files and short-circuits further request processing.
  4. El middleware de directivas de cookies (UseCookiePolicy) permite que la aplicación cumpla con las normas del Reglamento general de protección de datos (RGPD) de la Unión Europea.Cookie Policy Middleware (UseCookiePolicy) conforms the app to the EU General Data Protection Regulation (GDPR) regulations.
  5. El middleware de autenticación (UseAuthentication) intenta autenticar al usuarios antes de que se le permita acceder a los recursos protegidos.Authentication Middleware (UseAuthentication) attempts to authenticate the user before they're allowed access to secure resources.
  6. El middleware de sesiones (UseSession) establece y mantiene el estado de sesión.Session Middleware (UseSession) establishes and maintains session state. Si la aplicación usa el estado de sesión, llame al middleware de sesiones después del middleware de directivas de cookies y antes del middleware de MVC.If the app uses session state, call Session Middleware after Cookie Policy Middleware and before MVC Middleware.
  7. MVC (UseMvc) para agregar MVC a la canalización de la solicitud.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();
}

En el código de ejemplo anterior, cada método de extensión de software intermedio se expone en IApplicationBuilder a través del espacio de nombres de Microsoft.AspNetCore.Builder.In the preceding example code, each middleware extension method is exposed on IApplicationBuilder through the Microsoft.AspNetCore.Builder namespace.

UseExceptionHandler es el primer componente de software intermedio que se agrega a la canalización.UseExceptionHandler is the first middleware component added to the pipeline. Por lo tanto, el software intermedio del controlador de excepciones detectará las excepciones que se produzcan en las llamadas posteriores.Therefore, the Exception Handler Middleware catches any exceptions that occur in later calls.

El software intermedio de archivos estáticos se llama al principio de la canalización para que pueda controlar solicitudes y realizar cortocircuitos sin pasar por los componentes restantes.Static File Middleware is called early in the pipeline so that it can handle requests and short-circuit without going through the remaining components. Este middleware no proporciona comprobaciones de autorización.The Static File Middleware provides no authorization checks. Los archivos que proporciona el middleware de archivos estáticos, incluidos los de wwwroot, están disponibles de forma pública.Any files served by Static File Middleware, including those under wwwroot, are publicly available. Para obtener más información sobre cómo proteger este tipo de archivos, vea Archivos estáticos en ASP.NET Core.For an approach to secure static files, see Archivos estáticos en ASP.NET Core.

Si el software intermedio de archivos estáticos no controla la solicitud, se pasará al software intermedio de autenticación (UseAuthentication), que realizará la autenticación.If the request isn't handled by the Static File Middleware, it's passed on to the Authentication Middleware (UseAuthentication), which performs authentication. Este software intermedio no cortocircuita las solicitudes sin autenticación.Authentication doesn't short-circuit unauthenticated requests. Aunque autentique solicitudes, la autorización (y también el rechazo) se producirán después de que MVC seleccione una página de Razor o un control y una acción de MVC concretos.Although Authentication Middleware authenticates requests, authorization (and rejection) occurs only after MVC selects a specific Razor Page or MVC controller and action.

En el ejemplo siguiente se muestra un orden de software intermedio en el que el software intermedio de archivos estáticos controla las solicitudes de archivos estáticos antes del software intermedio de compresión de respuestas.The following example demonstrates a middleware order where requests for static files are handled by Static File Middleware before Response Compression Middleware. Los archivos estáticos no se comprimen en este orden de software intermedio.Static files aren't compressed with this middleware order. Las respuestas de MVC de UseMvcWithDefaultRoute se pueden comprimir.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 y MapUse, Run, and Map

Puede configurar la canalización HTTP con Use, Run y Map.Configure the HTTP pipeline using Use, Run, and Map. El método Use puede cortocircuitar la canalización (solo si no llama a un delegado de solicitudes next).The Use method can short-circuit the pipeline (that is, if it doesn't call a next request delegate). Run es una convención y es posible que algunos componentes de middleware expongan métodos Run[Middleware] que se ejecutan al final de la canalización.Run is a convention, and some middleware components may expose Run[Middleware] methods that run at the end of the pipeline.

Las extensiones Map se usan como convenciones para la creación de ramas en la canalización.Map extensions are used as a convention for branching the pipeline. Map crea una rama de la canalización de solicitudes según las coincidencias de la ruta de solicitud proporcionada.Map branches the request pipeline based on matches of the given request path. Si la ruta de solicitud comienza con la ruta proporcionada, se ejecuta la creación de la rama.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>");
        });
    }
}

En la siguiente tabla se muestran las solicitudes y las respuestas de http://localhost:1234 con el código anterior.The following table shows the requests and responses from http://localhost:1234 using the previous code.

RequestRequest RespuestaResponse
localhost:1234localhost:1234 Saludos del delegado sin Map.Hello from non-Map delegate.
localhost:1234/map1localhost:1234/map1 Prueba 1 de MapMap Test 1
localhost:1234/map2localhost:1234/map2 Prueba 2 de MapMap Test 2
localhost:1234/map3localhost:1234/map3 Saludos del delegado sin Map.Hello from non-Map delegate.

Cuando se usa Map, los segmentos de ruta que coincidan se eliminan de HttpRequest.Path y se anexan a HttpRequest.PathBase para cada solicitud.When Map is used, the matched path segments are removed from HttpRequest.Path and appended to HttpRequest.PathBase for each request.

MapWhen crea una rama de la canalización de solicitudes según el resultado del predicado proporcionado.MapWhen branches the request pipeline based on the result of the given predicate. Se puede usar cualquier predicado de tipo Func<HttpContext, bool> para asignar solicitudes a nuevas ramas de la canalización.Any predicate of type Func<HttpContext, bool> can be used to map requests to a new branch of the pipeline. En el ejemplo siguiente se usa un predicado para detectar la presencia de una branch variable de cadena de consulta: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>");
        });
    }
}

En la siguiente tabla se muestran las solicitudes y las respuestas de http://localhost:1234 con el código anterior.The following table shows the requests and responses from http://localhost:1234 using the previous code.

RequestRequest RespuestaResponse
localhost:1234localhost:1234 Saludos del delegado sin Map.Hello from non-Map delegate.
localhost:1234/?branch=masterlocalhost:1234/?branch=master Rama usada = masterBranch used = master

Map admite la anidación, por ejemplo:Map supports nesting, for example:

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

Map puede hacer coincidir varios segmentos a la vez: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.");
        });
    }
}

Middleware integradoBuilt-in middleware

ASP.NET Core incluye los componentes de software intermedio siguientes.ASP.NET Core ships with the following middleware components. En la columna Orden se proporcionan notas sobre la ubicación del middleware en la canalización de procesamiento de solicitudes, así como las condiciones con las que podría finalizar el procesamiento de solicitudes.The Order column provides notes on middleware placement in the request processing pipeline and under what conditions the middleware may terminate request processing. Cuando un middleware cortocircuita la canalización de procesamiento de solicitudes e impide el procesamiento de una solicitud por parte de middleware descendente adicional, se llama middleware de terminal.When a middleware short-circuits the request processing pipeline and prevents further downstream middleware from processing a request, it's called a terminal middleware. Para más información sobre cómo cortocircuitar, consulte la sección Creación de una canalización de middleware con IApplicationBuilder.For more information on short-circuiting, see the Create a middleware pipeline with IApplicationBuilder section.

Software intermedioMiddleware DescripciónDescription OrdenarOrder
AutenticaciónAuthentication Proporciona compatibilidad con autenticación.Provides authentication support. Antes de que se necesite HttpContext.User.Before HttpContext.User is needed. Terminal para devoluciones de llamadas OAuth.Terminal for OAuth callbacks.
Directiva de cookiesCookie Policy Realiza un seguimiento del consentimiento de los usuarios para almacenar información personal y aplica los estándares mínimos para los campos de las cookies, como secure y SameSite.Tracks consent from users for storing personal information and enforces minimum standards for cookie fields, such as secure and SameSite. Antes del middleware que emite las cookies.Before middleware that issues cookies. Ejemplos: autenticación, sesión y MVC (TempData).Examples: Authentication, Session, MVC (TempData).
CORSCORS Configura el uso compartido de recursos entre orígenes.Configures Cross-Origin Resource Sharing. Antes de los componentes que usan CORS.Before components that use CORS.
DiagnósticoDiagnostics Varios middleware independientes que proporcionan una página de excepciones para el desarrollador, control de excepciones, páginas de códigos de estado y la página web predeterminada para las nuevas aplicaciones.Several separate middlewares that provide a developer exception page, exception handling, status code pages, and the default web page for new apps. Antes de los componentes que generan errores.Before components that generate errors. Terminal para excepciones o con el fin de proporcionar la página web predeterminada para las nuevas aplicaciones.Terminal for exceptions or serving the default web page for new apps.
Encabezados reenviadosForwarded Headers Reenvía encabezados con proxy a la solicitud actual.Forwards proxied headers onto the current request. Antes de los componentes que consumen los campos actualizados.Before components that consume the updated fields. Ejemplos: esquema, host, IP de cliente y método.Examples: scheme, host, client IP, method.
Comprobación de estadoHealth Check Comprueba el estado de una aplicación ASP.NET Core y sus dependencias, como la comprobación de disponibilidad de base de datos.Checks the health of an ASP.NET Core app and its dependencies, such as checking database availability. Terminal si una solicitud coincide con un punto de conexión de comprobación de estado.Terminal if a request matches a health check endpoint.
Invalidación del método HTTPHTTP Method Override Permite que una solicitud POST entrante invalide el método.Allows an incoming POST request to override the method. Antes de los componentes que consumen el método actualizado.Before components that consume the updated method.
Redireccionamiento de HTTPSHTTPS Redirection Redirija todas las solicitudes HTTP a HTTPS.Redirect all HTTP requests to HTTPS. Antes de los componentes que consumen la dirección URL.Before components that consume the URL.
Seguridad de transporte estricta de HTTP (HSTS)HTTP Strict Transport Security (HSTS) Middleware de mejora de seguridad que agrega un encabezado de respuesta especial.Security enhancement middleware that adds a special response header. Antes de que se envíen las respuestas y después de los componentes que modifican las solicitudes.Before responses are sent and after components that modify requests. Ejemplos: encabezados reenviados y reescritura de URL.Examples: Forwarded Headers, URL Rewriting.
MVCMVC Procesa las solicitudes con MVC/Razor Pages.Processes requests with MVC/Razor Pages. Si hay una solicitud que coincida con una ruta, será final.Terminal if a request matches a route.
OWINOWIN Puede interoperar con aplicaciones, servidores y software intermedio basados en OWIN.Interop with OWIN-based apps, servers, and middleware. Si el software intermedio de OWIN procesa completamente la solicitud, será final.Terminal if the OWIN Middleware fully processes the request.
Almacenamiento en caché de respuestasResponse Caching Proporciona compatibilidad con la captura de respuestas.Provides support for caching responses. Antes de los componentes que requieren el almacenamiento en caché.Before components that require caching.
Compresión de respuestaResponse Compression Proporciona compatibilidad con la compresión de respuestas.Provides support for compressing responses. Antes de los componentes que requieren compresión.Before components that require compression.
Localización de solicitudesRequest Localization Proporciona compatibilidad con ubicación.Provides localization support. Antes de los componentes que dependen de la ubicación.Before localization sensitive components.
Enrutamiento de punto de conexiónEndpoint Routing Define y restringe las rutas de la solicitud.Defines and constrains request routes. Terminal para rutas que coincidan.Terminal for matching routes.
SesiónSession Proporciona compatibilidad con la administración de sesiones de usuario.Provides support for managing user sessions. Antes de los componentes que requieren Session.Before components that require Session.
Archivos estáticosStatic Files Proporciona compatibilidad con la proporción de archivos estáticos y la exploración de directorios.Provides support for serving static files and directory browsing. Si hay una solicitud que coincida con un archivo, será final.Terminal if a request matches a file.
Reescritura de URLURL Rewrite Proporciona compatibilidad con la reescritura de direcciones URL y la redirección de solicitudes.Provides support for rewriting URLs and redirecting requests. Antes de los componentes que consumen la dirección URL.Before components that consume the URL.
WebSocketsWebSockets Habilita el protocolo WebSockets.Enables the WebSockets protocol. Antes de los componentes necesarios para aceptar solicitudes de WebSocket.Before components that are required to accept WebSocket requests.

Recursos adicionalesAdditional resources