Routage dans ASP.NET CoreRouting in ASP.NET Core

Par Ryan Nowak, Kirk Larkinet Rick AndersonBy Ryan Nowak, Kirk Larkin, and Rick Anderson

Le routage est responsable de la mise en correspondance des demandes HTTP entrantes et de la distribution de ces requêtes aux points de terminaison exécutables de l’application.Routing is responsible for matching incoming HTTP requests and dispatching those requests to the app's executable endpoints. Les points de terminaison sont les unités de code de gestion des requêtes exécutables de l’application.Endpoints are the app's units of executable request-handling code. Les points de terminaison sont définis dans l’application et configurés au démarrage de l’application.Endpoints are defined in the app and configured when the app starts. Le processus de correspondance de point de terminaison peut extraire des valeurs de l’URL de la demande et fournir ces valeurs pour le traitement des demandes.The endpoint matching process can extract values from the request's URL and provide those values for request processing. À l’aide des informations de point de terminaison de l’application, le routage est également en mesure de générer des URL qui mappent aux points de terminaison.Using endpoint information from the app, routing is also able to generate URLs that map to endpoints.

Les applications peuvent configurer le routage à l’aide de :Apps can configure routing using:

Ce document traite des détails de bas niveau du routage de ASP.NET Core.This document covers low-level details of ASP.NET Core routing. Pour plus d’informations sur la configuration du routage :For information on configuring routing:

Le système de routage des points de terminaison décrit dans ce document s’applique à ASP.NET Core 3,0 et versions ultérieures.The endpoint routing system described in this document applies to ASP.NET Core 3.0 and later. Pour plus d’informations sur le système de routage précédent basé sur IRouter , sélectionnez la version ASP.NET Core 2,1 à l’aide de l’une des approches suivantes :For information on the previous routing system based on IRouter, select the ASP.NET Core 2.1 version using one of the following approaches:

Afficher ou télécharger l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Les exemples de téléchargement de ce document sont activés par une Startup classe spécifique.The download samples for this document are enabled by a specific Startup class. Pour exécuter un exemple spécifique, modifiez Program.cs pour appeler la Startup classe souhaitée.To run a specific sample, modify Program.cs to call the desired Startup class.

Concepts de base du routageRouting basics

Tous les modèles de ASP.NET Core incluent le routage dans le code généré.All ASP.NET Core templates include routing in the generated code. Le routage est inscrit dans le pipeline de l' intergiciel (middleware ) dans Startup.Configure .Routing is registered in the middleware pipeline in Startup.Configure.

Le code suivant illustre un exemple de routage de base :The following code shows a basic example of routing:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Le routage utilise une paire d’intergiciels (middleware), inscrite par UseRouting et UseEndpoints :Routing uses a pair of middleware, registered by UseRouting and UseEndpoints:

  • UseRouting Ajoute la correspondance d’itinéraire au pipeline de l’intergiciel (middleware).UseRouting adds route matching to the middleware pipeline. Cet intergiciel (middleware) examine l’ensemble des points de terminaison définis dans l’application et sélectionne la meilleure correspondance en fonction de la demande.This middleware looks at the set of endpoints defined in the app, and selects the best match based on the request.
  • UseEndpoints Ajoute l’exécution du point de terminaison au pipeline d’intergiciel (middleware).UseEndpoints adds endpoint execution to the middleware pipeline. Il exécute le délégué associé au point de terminaison sélectionné.It runs the delegate associated with the selected endpoint.

L’exemple précédent comprend un seul itinéraire vers le point de terminaison de code à l’aide de la méthode MapGet :The preceding example includes a single route to code endpoint using the MapGet method:

  • Quand une GET requête HTTP est envoyée à l’URL racine / :When an HTTP GET request is sent to the root URL /:
    • Le délégué de requête indiqué s’exécute.The request delegate shown executes.
    • Hello World! est écrit dans la réponse HTTP.Hello World! is written to the HTTP response. Par défaut, l’URL racine / est https://localhost:5001/ .By default, the root URL / is https://localhost:5001/.
  • Si la méthode de demande n’est pas GET ou si l’URL racine n’est pas / , aucun itinéraire ne correspond et un http 404 est retourné.If the request method is not GET or the root URL is not /, no route matches and an HTTP 404 is returned.

Point de terminaisonEndpoint

La MapGet méthode est utilisée pour définir un point de terminaison.The MapGet method is used to define an endpoint. Un point de terminaison est un point qui peut être :An endpoint is something that can be:

  • Sélectionné en faisant correspondre l’URL et la méthode HTTP.Selected, by matching the URL and HTTP method.
  • Exécuté, en exécutant le délégué.Executed, by running the delegate.

Les points de terminaison qui peuvent être mis en correspondance et exécutés par l’application sont configurés dans UseEndpoints .Endpoints that can be matched and executed by the app are configured in UseEndpoints. Par exemple, MapGet , MapPost et les méthodes similaires connectent les délégués de demande au système de routage.For example, MapGet, MapPost, and similar methods connect request delegates to the routing system. Des méthodes supplémentaires peuvent être utilisées pour connecter les fonctionnalités de ASP.NET Core Framework au système de routage :Additional methods can be used to connect ASP.NET Core framework features to the routing system:

L’exemple suivant illustre le routage avec un modèle d’itinéraire plus sophistiqué :The following example shows routing with a more sophisticated route template:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/hello/{name:alpha}", async context =>
    {
        var name = context.Request.RouteValues["name"];
        await context.Response.WriteAsync($"Hello {name}!");
    });
});

La chaîne /hello/{name:alpha} est un modèle de routage.The string /hello/{name:alpha} is a route template. Il permet de configurer la mise en correspondance du point de terminaison.It is used to configure how the endpoint is matched. Dans ce cas, le modèle correspond à :In this case, the template matches:

  • Une URL telle que /hello/RyanA URL like /hello/Ryan
  • Tout chemin d’accès d’URL qui commence par /hello/ , suivi d’une séquence de caractères alphabétiques.Any URL path that begins with /hello/ followed by a sequence of alphabetic characters. :alpha applique une contrainte d’itinéraire qui correspond uniquement aux caractères alphabétiques.:alpha applies a route constraint that matches only alphabetic characters. Les contraintes de routage sont expliquées plus loin dans ce document.Route constraints are explained later in this document.

Le deuxième segment du chemin d’URL {name:alpha} :The second segment of the URL path, {name:alpha}:

Le système de routage des points de terminaison décrit dans ce document est nouveau à partir de ASP.NET Core 3,0.The endpoint routing system described in this document is new as of ASP.NET Core 3.0. Toutefois, toutes les versions de ASP.NET Core prennent en charge le même jeu de fonctionnalités de modèle de routage et de contraintes de routage.However, all versions of ASP.NET Core support the same set of route template features and route constraints.

L’exemple suivant illustre le routage avec des contrôles d’intégrité et l’autorisation :The following example shows routing with health checks and authorization:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Matches request to an endpoint.
    app.UseRouting();

    // Endpoint aware middleware. 
    // Middleware can use metadata from the matched endpoint.
    app.UseAuthentication();
    app.UseAuthorization();

    // Execute the matched endpoint.
    app.UseEndpoints(endpoints =>
    {
        // Configure the Health Check endpoint and require an authorized user.
        endpoints.MapHealthChecks("/healthz").RequireAuthorization();

        // Configure another endpoint, no authorization requirements.
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Si vous souhaitez voir les commentaires de code traduits dans des langues autres que l’anglais, faites-le nous savoir dans ce problème de discussion GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

L’exemple précédent montre comment :The preceding example demonstrates how:

  • L’intergiciel d’autorisation peut être utilisé avec le routage.The authorization middleware can be used with routing.
  • Les points de terminaison peuvent être utilisés pour configurer le comportement d’autorisation.Endpoints can be used to configure authorization behavior.

L' MapHealthChecks appel ajoute un point de terminaison de contrôle d’intégrité.The MapHealthChecks call adds a health check endpoint. Le chaînage RequireAuthorization sur cet appel joint une stratégie d’autorisation au point de terminaison.Chaining RequireAuthorization on to this call attaches an authorization policy to the endpoint.

UseAuthenticationL’appel de et UseAuthorization ajoute l’intergiciel (middleware) d’authentification et d’autorisation.Calling UseAuthentication and UseAuthorization adds the authentication and authorization middleware. Ces intergiciels sont placés entre UseRouting et UseEndpoints afin de pouvoir :These middleware are placed between UseRouting and UseEndpoints so that they can:

  • Consultez le point de terminaison sélectionné par UseRouting .See which endpoint was selected by UseRouting.
  • Appliquez une stratégie d’autorisation avant UseEndpoints les distributions au point de terminaison.Apply an authorization policy before UseEndpoints dispatches to the endpoint.

Métadonnées de point de terminaisonEndpoint metadata

Dans l’exemple précédent, il existe deux points de terminaison, mais seul le point de terminaison de contrôle d’intégrité a une stratégie d’autorisation attachée.In the preceding example, there are two endpoints, but only the health check endpoint has an authorization policy attached. Si la demande correspond au point de terminaison de contrôle d’intégrité, /healthz une vérification d’autorisation est effectuée.If the request matches the health check endpoint, /healthz, an authorization check is performed. Cela démontre que des données supplémentaires peuvent être attachées aux points de terminaison.This demonstrates that endpoints can have extra data attached to them. Ces données supplémentaires sont appelées métadonnéesde point de terminaison :This extra data is called endpoint metadata:

  • Les métadonnées peuvent être traitées par un intergiciel (middleware) qui prend en charge le routage.The metadata can be processed by routing-aware middleware.
  • Les métadonnées peuvent être de n’importe quel type .NET.The metadata can be of any .NET type.

Concepts de routageRouting concepts

Le système de routage s’appuie sur le pipeline de l’intergiciel (middleware) en ajoutant le puissant concept de point de terminaison .The routing system builds on top of the middleware pipeline by adding the powerful endpoint concept. Les points de terminaison représentent les unités de la fonctionnalité de l’application qui sont distinctes les unes des autres en termes de routage, d’autorisation et de tout nombre de systèmes de ASP.NET Core.Endpoints represent units of the app's functionality that are distinct from each other in terms of routing, authorization, and any number of ASP.NET Core's systems.

Définition de point de terminaison ASP.NET CoreASP.NET Core endpoint definition

Un point de terminaison de ASP.NET Core est :An ASP.NET Core endpoint is:

Le code suivant montre comment récupérer et inspecter le point de terminaison correspondant à la requête actuelle :The following code shows how to retrieve and inspect the endpoint matching the current request:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.Use(next => context =>
    {
        var endpoint = context.GetEndpoint();
        if (endpoint is null)
        {
            return Task.CompletedTask;
        }
        
        Console.WriteLine($"Endpoint: {endpoint.DisplayName}");

        if (endpoint is RouteEndpoint routeEndpoint)
        {
            Console.WriteLine("Endpoint has route pattern: " +
                routeEndpoint.RoutePattern.RawText);
        }

        foreach (var metadata in endpoint.Metadata)
        {
            Console.WriteLine($"Endpoint has metadata: {metadata}");
        }

        return Task.CompletedTask;
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Le point de terminaison, s’il est sélectionné, peut être récupéré à partir du HttpContext .The endpoint, if selected, can be retrieved from the HttpContext. Ses propriétés peuvent être inspectées.Its properties can be inspected. Les objets de point de terminaison sont immuables et ne peuvent pas être modifiés après la création.Endpoint objects are immutable and cannot be modified after creation. Le type de point de terminaison le plus courant est RouteEndpoint .The most common type of endpoint is a RouteEndpoint. RouteEndpoint contient des informations qui peuvent être sélectionnées par le système de routage.RouteEndpoint includes information that allows it to be to selected by the routing system.

Dans le code précédent, application. Utiliser configure un intergiciel (middleware) en ligne.In the preceding code, app.Use configures an in-line middleware.

Le code suivant montre que, en fonction de l’endroit où app.Use est appelé dans le pipeline, il se peut qu’il n’y ait pas de point de terminaison :The following code shows that, depending on where app.Use is called in the pipeline, there may not be an endpoint:

// Location 1: before routing runs, endpoint is always null here
app.Use(next => context =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match
app.Use(next => context =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

app.UseEndpoints(endpoints =>
{
    // Location 3: runs when this endpoint matches
    endpoints.MapGet("/", context =>
    {
        Console.WriteLine(
            $"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
        return Task.CompletedTask;
    }).WithDisplayName("Hello");
});

// Location 4: runs after UseEndpoints - will only run if there was no match
app.Use(next => context =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

Cet exemple précédent ajoute des Console.WriteLine instructions qui indiquent si un point de terminaison a été sélectionné ou non.This preceding sample adds Console.WriteLine statements that display whether or not an endpoint has been selected. Par souci de clarté, l’exemple assigne un nom complet au / point de terminaison fourni.For clarity, the sample assigns a display name to the provided / endpoint.

L’exécution de ce code avec une URL de / affiche :Running this code with a URL of / displays:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

L’exécution de ce code avec d’autres URL affiche :Running this code with any other URL displays:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)

Cette sortie illustre ce qui suit :This output demonstrates that:

  • Le point de terminaison est toujours null avant que UseRouting ne soit appelé.The endpoint is always null before UseRouting is called.
  • Si une correspondance est trouvée, le point de terminaison n’a pas la valeur null entre UseRouting et UseEndpoints .If a match is found, the endpoint is non-null between UseRouting and UseEndpoints.
  • L' UseEndpoints intergiciel est Terminal quand une correspondance est trouvée.The UseEndpoints middleware is terminal when a match is found. L' intergiciel (middleware) Terminal est défini plus loin dans ce document.Terminal middleware is defined later in this document.
  • L’intergiciel (middleware) après l' UseEndpoints exécution uniquement quand aucune correspondance n’est trouvée.The middleware after UseEndpoints execute only when no match is found.

L' UseRouting intergiciel utilise la méthode SetEndpoint pour attacher le point de terminaison au contexte actuel.The UseRouting middleware uses the SetEndpoint method to attach the endpoint to the current context. Il est possible de remplacer l' UseRouting intergiciel par une logique personnalisée tout en bénéficiant des avantages de l’utilisation des points de terminaison.It's possible to replace the UseRouting middleware with custom logic and still get the benefits of using endpoints. Les points de terminaison sont une primitive de bas niveau, comme l’intergiciel (middleware), et ne sont pas couplés à l’implémentation du routage.Endpoints are a low-level primitive like middleware, and aren't coupled to the routing implementation. La plupart des applications n’ont pas besoin d’être remplacées UseRouting par une logique personnalisée.Most apps don't need to replace UseRouting with custom logic.

L' UseEndpoints intergiciel (middleware) est conçu pour être utilisé en tandem avec l' UseRouting intergiciel (middleware).The UseEndpoints middleware is designed to be used in tandem with the UseRouting middleware. La logique de base pour exécuter un point de terminaison n’est pas compliquée.The core logic to execute an endpoint isn't complicated. Utilisez GetEndpoint pour récupérer le point de terminaison, puis appelez sa RequestDelegate propriété.Use GetEndpoint to retrieve the endpoint, and then invoke its RequestDelegate property.

Le code suivant montre comment l’intergiciel (middleware) peut influencer ou réagir au routage :The following code demonstrates how middleware can influence or react to routing:

public class IntegratedMiddlewareStartup
{ 
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Location 1: Before routing runs. Can influence request before routing runs.
        app.UseHttpMethodOverride();

        app.UseRouting();

        // Location 2: After routing runs. Middleware can match based on metadata.
        app.Use(next => context =>
        {
            var endpoint = context.GetEndpoint();
            if (endpoint?.Metadata.GetMetadata<AuditPolicyAttribute>()?.NeedsAudit
                                                                            == true)
            {
                Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
            }

            return next(context);
        });

        app.UseEndpoints(endpoints =>
        {         
            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync("Hello world!");
            });

            // Using metadata to configure the audit policy.
            endpoints.MapGet("/sensitive", async context =>
            {
                await context.Response.WriteAsync("sensitive data");
            })
            .WithMetadata(new AuditPolicyAttribute(needsAudit: true));
        });

    } 
}

public class AuditPolicyAttribute : Attribute
{
    public AuditPolicyAttribute(bool needsAudit)
    {
        NeedsAudit = needsAudit;
    }

    public bool NeedsAudit { get; }
}

L’exemple précédent illustre deux concepts importants :The preceding example demonstrates two important concepts:

  • L’intergiciel peut s’exécuter avant UseRouting de modifier les données sur lesquelles le routage fonctionne.Middleware can run before UseRouting to modify the data that routing operates upon.
  • L’intergiciel peut s’exécuter entre UseRouting et UseEndpoints pour traiter les résultats du routage avant l’exécution du point de terminaison.Middleware can run between UseRouting and UseEndpoints to process the results of routing before the endpoint is executed.
    • Intergiciel qui s’exécute entre UseRouting et UseEndpoints :Middleware that runs between UseRouting and UseEndpoints:
      • Inspecte généralement les métadonnées pour comprendre les points de terminaison.Usually inspects metadata to understand the endpoints.
      • Prend souvent des décisions de sécurité, comme c’est le cas par UseAuthorization et UseCors .Often makes security decisions, as done by UseAuthorization and UseCors.
    • La combinaison d’intergiciels (middleware) et de métadonnées permet de configurer des stratégies par point de terminaison.The combination of middleware and metadata allows configuring policies per-endpoint.

Le code précédent montre un exemple d’un intergiciel (middleware) personnalisé qui prend en charge les stratégies par point de terminaison.The preceding code shows an example of a custom middleware that supports per-endpoint policies. L’intergiciel écrit un Journal d’audit de l’accès aux données sensibles sur la console.The middleware writes an audit log of access to sensitive data to the console. L’intergiciel peut être configuré pour auditer un point de terminaison avec les AuditPolicyAttribute métadonnées.The middleware can be configured to audit an endpoint with the AuditPolicyAttribute metadata. Cet exemple illustre un modèle d' abonnement dans lequel seuls les points de terminaison marqués comme sensibles sont audités.This sample demonstrates an opt-in pattern where only endpoints that are marked as sensitive are audited. Il est possible de définir cette logique en sens inverse, en auditant tout ce qui n’est pas marqué comme sécurisé, par exemple.It's possible to define this logic in reverse, auditing everything that isn't marked as safe, for example. Le système de métadonnées du point de terminaison est flexible.The endpoint metadata system is flexible. Cette logique peut être conçue de la manière qui convient le mieux au cas d’usage.This logic could be designed in whatever way suits the use case.

L’exemple de code précédent est destiné à illustrer les concepts de base des points de terminaison.The preceding sample code is intended to demonstrate the basic concepts of endpoints. L’exemple n’est pas destiné à une utilisation en production.The sample is not intended for production use. Une version plus complète d’un intergiciel (middleware) de journaux d’audit :A more complete version of an audit log middleware would:

  • Connectez-vous à un fichier ou à une base de données.Log to a file or database.
  • Incluez des détails tels que l’utilisateur, l’adresse IP, le nom du point de terminaison sensible, et bien plus encore.Include details such as the user, IP address, name of the sensitive endpoint, and more.

Les métadonnées de la stratégie d’audit AuditPolicyAttribute sont définies en tant que Attribute pour une utilisation plus facile avec les infrastructures basées sur des classes telles que les contrôleurs et SignalR .The audit policy metadata AuditPolicyAttribute is defined as an Attribute for easier use with class-based frameworks such as controllers and SignalR. Lors de l’utilisation de l’itinéraire vers le code:When using route to code:

  • Les métadonnées sont jointes à une API de générateur.Metadata is attached with a builder API.
  • Les infrastructures basées sur des classes incluent tous les attributs de la méthode et de la classe correspondantes lors de la création de points de terminaison.Class-based frameworks include all attributes on the corresponding method and class when creating endpoints.

Les meilleures pratiques pour les types de métadonnées sont de les définir comme des interfaces ou des attributs.The best practices for metadata types are to define them either as interfaces or attributes. Les interfaces et les attributs permettent de réutiliser le code.Interfaces and attributes allow code reuse. Le système de métadonnées est flexible et n’impose aucune restriction.The metadata system is flexible and doesn't impose any limitations.

Comparaison entre un intergiciel et un routage de terminauxComparing a terminal middleware and routing

L’exemple de code suivant compare l’utilisation de l’intergiciel avec le routage :The following code sample contrasts using middleware with using routing:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Approach 1: Writing a terminal middleware.
    app.Use(next => async context =>
    {
        if (context.Request.Path == "/")
        {
            await context.Response.WriteAsync("Hello terminal middleware!");
            return;
        }

        await next(context);
    });

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        // Approach 2: Using routing.
        endpoints.MapGet("/Movie", async context =>
        {
            await context.Response.WriteAsync("Hello routing!");
        });
    });
}

Le style d’intergiciel (middleware) présenté avec est l’intergiciel (middleware) de Approach 1: Terminal.The style of middleware shown with Approach 1: is terminal middleware. Il s’agit de l’intergiciel (middleware) Terminal Server, car il effectue une opération de correspondance :It's called terminal middleware because it does a matching operation:

  • L’opération de correspondance dans l’exemple précédent concerne Path == "/" l’intergiciel et le Path == "/Movie" routage.The matching operation in the preceding sample is Path == "/" for the middleware and Path == "/Movie" for routing.
  • Lorsqu’une correspondance est réussie, elle exécute certaines fonctionnalités et retourne, plutôt que d’appeler l' next intergiciel (middleware).When a match is successful, it executes some functionality and returns, rather than invoking the next middleware.

Il s’agit de l’intergiciel (middleware) Terminal Server, car il met fin à la recherche, exécute certaines fonctionnalités, puis retourne.It's called terminal middleware because it terminates the search, executes some functionality, and then returns.

Comparaison entre un intergiciel et un routage de terminaux :Comparing a terminal middleware and routing:

  • Les deux approches permettent d’arrêter le pipeline de traitement :Both approaches allow terminating the processing pipeline:
    • L’intergiciel termine le pipeline en retournant plutôt qu’en appelant next .Middleware terminates the pipeline by returning rather than invoking next.
    • Les points de terminaison sont toujours des terminaux.Endpoints are always terminal.
  • L’intergiciel (middleware) Terminal permet de positionner l’intergiciel (middleware) à un emplacement arbitraire dans le pipeline :Terminal middleware allows positioning the middleware at an arbitrary place in the pipeline:
    • Les points de terminaison s’exécutent à la position de UseEndpoints .Endpoints execute at the position of UseEndpoints.
  • L’intergiciel (middleware) Terminal permet au code arbitraire de déterminer quand l’intergiciel correspond à :Terminal middleware allows arbitrary code to determine when the middleware matches:
    • Le code de correspondance d’itinéraire personnalisé peut être détaillé et difficile à écrire correctement.Custom route matching code can be verbose and difficult to write correctly.
    • Le routage fournit des solutions simples pour les applications classiques.Routing provides straightforward solutions for typical apps. La plupart des applications n’ont pas besoin de code de correspondance d’itinéraire personnalisé.Most apps don't require custom route matching code.
  • Interface des points de terminaison avec un intergiciel (middleware) tel que UseAuthorization et UseCors .Endpoints interface with middleware such as UseAuthorization and UseCors.
    • L’utilisation d’un intergiciel (middleware) terminal avec UseAuthorization ou UseCors nécessite une interface manuelle avec le système d’autorisation.Using a terminal middleware with UseAuthorization or UseCors requires manual interfacing with the authorization system.

Un point de terminaison définit les deux :An endpoint defines both:

  • Délégué pour traiter les demandes.A delegate to process requests.
  • Collection de métadonnées arbitraires.A collection of arbitrary metadata. Les métadonnées sont utilisées pour implémenter des problèmes transversaux en fonction des stratégies et de la configuration attachées à chaque point de terminaison.The metadata is used to implement cross-cutting concerns based on policies and configuration attached to each endpoint.

L’intergiciel (middleware) terminal peut être un outil efficace, mais peut nécessiter les éléments suivants :Terminal middleware can be an effective tool, but can require:

  • Une quantité significative de codage et de test.A significant amount of coding and testing.
  • Intégration manuelle avec d’autres systèmes pour atteindre le niveau de flexibilité souhaité.Manual integration with other systems to achieve the desired level of flexibility.

Envisagez l’intégration avec le routage avant d’écrire un intergiciel (middleware) Terminal.Consider integrating with routing before writing a terminal middleware.

Un intergiciel (middleware) terminal existant qui s’intègre à Map ou MapWhen peut généralement être converti en point de terminaison prenant en charge le routage.Existing terminal middleware that integrates with Map or MapWhen can usually be turned into a routing aware endpoint. MapHealthChecks illustre le modèle de routeur-Ware :MapHealthChecks demonstrates the pattern for router-ware:

  • Écrire une méthode d’extension sur IEndpointRouteBuilder .Write an extension method on IEndpointRouteBuilder.
  • Créez un pipeline d’intergiciel (middleware) imbriqué à l’aide de CreateApplicationBuilder .Create a nested middleware pipeline using CreateApplicationBuilder.
  • Attachez l’intergiciel au nouveau pipeline.Attach the middleware to the new pipeline. Dans ce cas, UseHealthChecks.In this case, UseHealthChecks.
  • Build pipeline d’intergiciel (middleware) dans un RequestDelegate .Build the middleware pipeline into a RequestDelegate.
  • Appelez Map et fournissez le nouveau pipeline d’intergiciel (middleware).Call Map and provide the new middleware pipeline.
  • Retourne l’objet générateur fourni par Map à partir de la méthode d’extension.Return the builder object provided by Map from the extension method.

Le code suivant illustre l’utilisation de MapHealthChecks:The following code shows use of MapHealthChecks:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Matches request to an endpoint.
    app.UseRouting();

    // Endpoint aware middleware. 
    // Middleware can use metadata from the matched endpoint.
    app.UseAuthentication();
    app.UseAuthorization();

    // Execute the matched endpoint.
    app.UseEndpoints(endpoints =>
    {
        // Configure the Health Check endpoint and require an authorized user.
        endpoints.MapHealthChecks("/healthz").RequireAuthorization();

        // Configure another endpoint, no authorization requirements.
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

L’exemple précédent montre pourquoi le retour de l’objet générateur est important.The preceding sample shows why returning the builder object is important. Le retour de l’objet générateur permet au développeur de l’application de configurer des stratégies telles que l’autorisation pour le point de terminaison.Returning the builder object allows the app developer to configure policies such as authorization for the endpoint. Dans cet exemple, l’intergiciel (middleware) des contrôles d’intégrité n’a pas d’intégration directe avec le système d’autorisation.In this example, the health checks middleware has no direct integration with the authorization system.

Le système de métadonnées a été créé en réponse aux problèmes rencontrés par les auteurs d’extensibilité à l’aide de l’intergiciel (middleware) Terminal.The metadata system was created in response to the problems encountered by extensibility authors using terminal middleware. Il est difficile pour chaque intergiciel d’implémenter sa propre intégration au système d’autorisation.It's problematic for each middleware to implement its own integration with the authorization system.

Correspondance d’URLURL matching

  • Est le processus par lequel le routage correspond à une requête entrante à un point de terminaison.Is the process by which routing matches an incoming request to an endpoint.
  • Est basé sur les données du chemin d’URL et des en-têtes.Is based on data in the URL path and headers.
  • Peut être étendu pour prendre en compte toutes les données de la requête.Can be extended to consider any data in the request.

Lors de l’exécution d’un intergiciel (middleware) de routage, il définit un Endpoint et des valeurs de route à une fonctionnalité de demande sur le HttpContext à partir de la requête actuelle :When a routing middleware executes, it sets an Endpoint and route values to a request feature on the HttpContext from the current request:

  • L’appel de HttpContext. GetEndpoint obtient le point de terminaison.Calling HttpContext.GetEndpoint gets the endpoint.
  • HttpRequest.RouteValues récupère la collection de valeurs d’itinéraire.HttpRequest.RouteValues gets the collection of route values.

L' intergiciel s’exécutant après l’intergiciel (middleware) de routage peut inspecter le point de terminaison et agir.Middleware running after the routing middleware can inspect the endpoint and take action. Par exemple, un intergiciel (middleware) d’autorisation peut interroger la collection de métadonnées du point de terminaison pour une stratégie d’autorisation.For example, an authorization middleware can interrogate the endpoint's metadata collection for an authorization policy. Une fois que tous les intergiciels dans le pipeline de traitement de requêtes sont exécutés, le délégué du point de terminaison sélectionné est appelé.After all of the middleware in the request processing pipeline is executed, the selected endpoint's delegate is invoked.

Le système de routage dans le routage de point de terminaison est responsable de toutes les décisions de distribution.The routing system in endpoint routing is responsible for all dispatching decisions. Étant donné que l’intergiciel applique des stratégies basées sur le point de terminaison sélectionné, il est important que :Because the middleware applies policies based on the selected endpoint, it's important that:

  • Toute décision qui peut affecter la distribution ou l’application de stratégies de sécurité est effectuée à l’intérieur du système de routage.Any decision that can affect dispatching or the application of security policies is made inside the routing system.

Avertissement

Pour la compatibilité descendante, lors de l’exécution d’un délégué de point de terminaison de contrôleur ou Razor de pages, les propriétés de RouteContext. RouteData sont définies sur les valeurs appropriées en fonction du traitement de la demande effectué jusqu’à présent.For backwards-compatibility, when a Controller or Razor Pages endpoint delegate is executed, the properties of RouteContext.RouteData are set to appropriate values based on the request processing performed thus far.

Le RouteContext type sera marqué comme obsolète dans une version ultérieure :The RouteContext type will be marked obsolete in a future release:

  • Migrez RouteData.Values vers HttpRequest.RouteValues .Migrate RouteData.Values to HttpRequest.RouteValues.
  • Migrez RouteData.DataTokens pour récupérer IDataTokensMetadata à partir des métadonnées de point de terminaison.Migrate RouteData.DataTokens to retrieve IDataTokensMetadata from the endpoint metadata.

La correspondance d’URL fonctionne dans un ensemble configurable de phases.URL matching operates in a configurable set of phases. Dans chaque phase, la sortie est un ensemble de correspondances.In each phase, the output is a set of matches. L’ensemble des correspondances peut être réduit davantage à la phase suivante.The set of matches can be narrowed down further by the next phase. L’implémentation du routage ne garantit pas un ordre de traitement pour les points de terminaison correspondants.The routing implementation does not guarantee a processing order for matching endpoints. Toutes les correspondances possibles sont traitées en même temps.All possible matches are processed at once. Les phases de correspondance d’URL se produisent dans l’ordre suivant.The URL matching phases occur in the following order. ASP.NET Core :ASP.NET Core:

  1. Traite le chemin d’accès de l’URL par rapport à l’ensemble des points de terminaison et de leurs modèles d’itinéraire, en collectant toutes les correspondances.Processes the URL path against the set of endpoints and their route templates, collecting all of the matches.
  2. Prend la liste précédente et supprime les correspondances qui échouent avec les contraintes d’itinéraire appliquées.Takes the preceding list and removes matches that fail with route constraints applied.
  3. Prend la liste précédente et supprime les correspondances qui échouent à l’ensemble des instances MatcherPolicy .Takes the preceding list and removes matches that fail the set of MatcherPolicy instances.
  4. Utilise EndpointSelector pour prendre une décision finale de la liste précédente.Uses the EndpointSelector to make a final decision from the preceding list.

La liste des points de terminaison est hiérarchisée en fonction des éléments suivants :The list of endpoints is prioritized according to:

Tous les points de terminaison correspondants sont traités dans chaque phase jusqu’à ce que le EndpointSelector soit atteint.All matching endpoints are processed in each phase until the EndpointSelector is reached. EndpointSelectorEst la phase finale.The EndpointSelector is the final phase. Il choisit le point de terminaison dont la priorité est la plus élevée parmi les correspondances comme meilleure correspondance.It chooses the highest priority endpoint from the matches as the best match. S’il existe d’autres correspondances avec la même priorité que la meilleure correspondance, une exception de correspondance ambiguë est levée.If there are other matches with the same priority as the best match, an ambiguous match exception is thrown.

La priorité d’itinéraire est calculée sur la base d’un modèle d’itinéraire plus spécifique qui reçoit une priorité plus élevée.The route precedence is computed based on a more specific route template being given a higher priority. Par exemple, considérez les modèles /hello et /{message} :For example, consider the templates /hello and /{message}:

  • Les deux correspondent au chemin de l’URL /hello .Both match the URL path /hello.
  • /hello est plus spécifique et par conséquent une priorité plus élevée./hello is more specific and therefore higher priority.

En général, la priorité des itinéraires est un bon choix pour choisir la meilleure correspondance pour les types de schémas d’URL utilisés dans la pratique.In general, route precedence does a good job of choosing the best match for the kinds of URL schemes used in practice. OrderÀ utiliser uniquement lorsque cela est nécessaire pour éviter une ambiguïté.Use Order only when necessary to avoid an ambiguity.

En raison des types d’extensibilité fournis par le routage, il n’est pas possible pour le système de routage de calculer à l’avance les itinéraires ambigus.Due to the kinds of extensibility provided by routing, it isn't possible for the routing system to compute ahead of time the ambiguous routes. Prenons l’exemple des modèles de routage /{message:alpha} et /{message:int} :Consider an example such as the route templates /{message:alpha} and /{message:int}:

  • La alpha contrainte correspond uniquement aux caractères alphabétiques.The alpha constraint matches only alphabetic characters.
  • La int contrainte correspond uniquement aux nombres.The int constraint matches only numbers.
  • Ces modèles ont la même priorité d’itinéraire, mais il n’y a pas d’URL unique correspondantes.These templates have the same route precedence, but there's no single URL they both match.
  • Si le système de routage a signalé une erreur d’ambiguïté au démarrage, il bloquerait ce cas d’utilisation valide.If the routing system reported an ambiguity error at startup, it would block this valid use case.

Avertissement

L’ordre des opérations à l’intérieur UseEndpoints n’influe pas sur le comportement du routage, à une exception près.The order of operations inside UseEndpoints doesn't influence the behavior of routing, with one exception. MapControllerRoute et MapAreaRoute attribuent automatiquement une valeur de commande à leurs points de terminaison en fonction de l’ordre dans lequel ils sont appelés.MapControllerRoute and MapAreaRoute automatically assign an order value to their endpoints based on the order they are invoked. Cela simule le comportement à long terme des contrôleurs sans le système de routage fournissant les mêmes garanties que les implémentations de routage plus anciennes.This simulates long-time behavior of controllers without the routing system providing the same guarantees as older routing implementations.

Dans l’implémentation héritée du routage, il est possible d’implémenter l’extensibilité du routage qui dépend de l’ordre dans lequel les itinéraires sont traités.In the legacy implementation of routing, it's possible to implement routing extensibility that has a dependency on the order in which routes are processed. Routage des points de terminaison dans ASP.NET Core 3,0 et versions ultérieures :Endpoint routing in ASP.NET Core 3.0 and later:

  • N’a pas de concept d’itinéraires.Doesn't have a concept of routes.
  • Ne fournit pas de garanties de classement.Doesn't provide ordering guarantees. Tous les points de terminaison sont traités à la fois.All endpoints are processed at once.

Si cela signifie que vous êtes bloqué en utilisant le système de routage hérité, ouvrez un problème GitHub pour obtenir de l’aide.If this means you're stuck using the legacy routing system, open a GitHub issue for assistance.

Priorité des modèles de routage et ordre de sélection des points de terminaisonRoute template precedence and endpoint selection order

La priorité des modèles de routage est un système qui affecte à chaque modèle de routage une valeur en fonction de sa spécificité.Route template precedence is a system that assigns each route template a value based on how specific it is. Priorité du modèle de routage :Route template precedence:

  • Évite d’avoir à ajuster l’ordre des points de terminaison dans les cas courants.Avoids the need to adjust the order of endpoints in common cases.
  • Tente de faire correspondre les attentes de sens commun du comportement de routage.Attempts to match the common-sense expectations of routing behavior.

Par exemple, considérez les modèles /Products/List et /Products/{id} .For example, consider templates /Products/List and /Products/{id}. Il serait raisonnable de supposer que /Products/List est une meilleure correspondance que /Products/{id} pour le chemin d’accès de l’URL /Products/List .It would be reasonable to assume that /Products/List is a better match than /Products/{id} for the URL path /Products/List. Le fonctionne car le segment littéral /List est considéré comme ayant une meilleure priorité que le segment de paramètres /{id} .The works because the literal segment /List is considered to have better precedence than the parameter segment /{id}.

Les détails du fonctionnement de la précédence sont associés à la façon dont les modèles de routage sont définis :The details of how precedence works are coupled to how route templates are defined:

  • Les modèles avec plus de segments sont considérés comme plus spécifiques.Templates with more segments are considered more specific.
  • Un segment avec du texte littéral est considéré comme plus spécifique qu’un segment de paramètres.A segment with literal text is considered more specific than a parameter segment.
  • Un segment de paramètre avec une contrainte est considéré comme plus spécifique qu’un segment sans.A parameter segment with a constraint is considered more specific than one without.
  • Un segment complexe est considéré comme un segment de paramètre spécifique avec une contrainte.A complex segment is considered as specific as a parameter segment with a constraint.
  • Les paramètres Catch-All sont les moins spécifiques.Catch-all parameters are the least specific. Pour obtenir des informations importantes sur les itinéraires d’interception, consultez la section « catch-all » dans la référence de modèle de routage .See catch-all in the Route template reference for important information on catch-all routes.

Consultez le code source sur GitHub pour obtenir une référence des valeurs exactes.See the source code on GitHub for a reference of exact values.

Concepts de génération d’URLURL generation concepts

Génération d’URL :URL generation:

  • Est le processus par lequel le routage peut créer un chemin d’URL basé sur un ensemble de valeurs d’itinéraire.Is the process by which routing can create a URL path based on a set of route values.
  • Permet une séparation logique entre les points de terminaison et les URL qui y accèdent.Allows for a logical separation between endpoints and the URLs that access them.

Le routage des points de terminaison comprend l' LinkGenerator API.Endpoint routing includes the LinkGenerator API. LinkGenerator est un service Singleton disponible à partir de di.LinkGenerator is a singleton service available from DI. L' LinkGenerator API peut être utilisée en dehors du contexte d’une demande en cours d’exécution.The LinkGenerator API can be used outside of the context of an executing request. Mvc. IUrlHelper et les scénarios qui reposent sur IUrlHelper , tels que les balises d’assistance, les applications auxiliaires html et les résultats d’action, utilisent l' LinkGenerator API en interne pour fournir des fonctionnalités de génération de liens.Mvc.IUrlHelper and scenarios that rely on IUrlHelper, such as Tag Helpers, HTML Helpers, and Action Results, use the LinkGenerator API internally to provide link generating capabilities.

Le générateur de liens est basé sur le concept d’une adresse et de schémas d’adresse.The link generator is backed by the concept of an address and address schemes. Un schéma d’adresse est un moyen de déterminer les points de terminaison à prendre en compte pour la génération de liens.An address scheme is a way of determining the endpoints that should be considered for link generation. Par exemple, les scénarios nom de l’itinéraire et valeurs de routage de nombreux utilisateurs sont familiarisés avec les contrôleurs et les Razor pages sont implémentées en tant que schéma d’adresse.For example, the route name and route values scenarios many users are familiar with from controllers and Razor Pages are implemented as an address scheme.

Le générateur de liens peut établir une liaison avec les contrôleurs et les Razor pages à l’aide des méthodes d’extension suivantes :The link generator can link to controllers and Razor Pages via the following extension methods:

Les surcharges de ces méthodes acceptent les arguments qui incluent le HttpContext .Overloads of these methods accept arguments that include the HttpContext. Ces méthodes sont fonctionnellement équivalentes à URL. action et URL. page, mais offrent une flexibilité et des options supplémentaires.These methods are functionally equivalent to Url.Action and Url.Page, but offer additional flexibility and options.

Les GetPath* méthodes sont très similaires à Url.Action et Url.Page , car elles génèrent un URI contenant un chemin d’accès absolu.The GetPath* methods are most similar to Url.Action and Url.Page, in that they generate a URI containing an absolute path. Les méthodes GetUri* génèrent toujours un URI absolu contenant un schéma et un hôte.The GetUri* methods always generate an absolute URI containing a scheme and host. Les méthodes qui acceptent un HttpContext génèrent un URI dans le contexte de la requête en cours d’exécution.The methods that accept an HttpContext generate a URI in the context of the executing request. Les valeurs de route ambiante , le chemin d’accès de base de l’URL, le schéma et l’hôte de la demande en cours d’exécution sont utilisés, sauf s’ils sont substitués.The ambient route values, URL base path, scheme, and host from the executing request are used unless overridden.

LinkGenerator est appelé avec une adresse.LinkGenerator is called with an address. La génération d’un URI se fait en deux étapes :Generating a URI occurs in two steps:

  1. Une adresse est liée à une liste de points de terminaison qui correspondent à l’adresse.An address is bound to a list of endpoints that match the address.
  2. Le RoutePattern de chaque point de terminaison est évalué jusqu’à ce qu’un modèle de route correspondant aux valeurs fournies soit trouvé.Each endpoint's RoutePattern is evaluated until a route pattern that matches the supplied values is found. Le résultat obtenu est combiné avec d’autres parties de l’URI fournies par le générateur de liens, puis il est retourné.The resulting output is combined with the other URI parts supplied to the link generator and returned.

Les méthodes fournies par LinkGenerator prennent en charge des fonctionnalités de génération de liens standard pour n’importe quel type d’adresse.The methods provided by LinkGenerator support standard link generation capabilities for any type of address. La méthode la plus pratique pour utiliser le générateur de liens est d’utiliser des méthodes d’extension qui effectuent des opérations pour un type d’adresse spécifique :The most convenient way to use the link generator is through extension methods that perform operations for a specific address type:

Méthode d’extensionExtension Method DescriptionDescription
GetPathByAddress Génère un URI avec un chemin absolu basé sur les valeurs fournies.Generates a URI with an absolute path based on the provided values.
GetUriByAddress Génère un URI absolu basé sur les valeurs fournies.Generates an absolute URI based on the provided values.

Avertissement

Faites attention aux implications suivantes de l’appel de méthodes LinkGenerator :Pay attention to the following implications of calling LinkGenerator methods:

  • Utilisez les méthodes d’extension GetUri* avec précaution dans une configuration d’application qui ne valide pas l’en-tête Host des requêtes entrantes.Use GetUri* extension methods with caution in an app configuration that doesn't validate the Host header of incoming requests. Si l' Host en-tête des demandes entrantes n’est pas validé, une entrée de demande non approuvée peut être renvoyée au client dans les URI d’une vue ou d’une page.If the Host header of incoming requests isn't validated, untrusted request input can be sent back to the client in URIs in a view or page. Nous recommandons que toutes les applications de production configurent leur serveur pour qu’il valide l’en-tête Host par rapport à des valeurs valides connues.We recommend that all production apps configure their server to validate the Host header against known valid values.

  • Utilisez LinkGenerator avec précaution dans le middleware en combinaison avec Map ou MapWhen.Use LinkGenerator with caution in middleware in combination with Map or MapWhen. Map* modifie le chemin de base de la requête en cours d’exécution, ce qui affecte la sortie de la génération de liens.Map* changes the base path of the executing request, which affects the output of link generation. Toutes les API LinkGenerator permettent la spécification d’un chemin de base.All of the LinkGenerator APIs allow specifying a base path. Spécifiez un chemin d’accès de base vide pour annuler l' Map* impact sur la génération de liens.Specify an empty base path to undo the Map* affect on link generation.

Exemple de middlewareMiddleware example

Dans l’exemple suivant, un intergiciel (middleware) utilise l' LinkGenerator API pour créer un lien vers une méthode d’action qui répertorie les produits du magasin.In the following example, a middleware uses the LinkGenerator API to create a link to an action method that lists store products. En utilisant le générateur de liens en l’injectant dans une classe et en appelant GenerateLink est disponible pour n’importe quelle classe dans une application :Using the link generator by injecting it into a class and calling GenerateLink is available to any class in an app:

public class ProductsLinkMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsLinkMiddleware(RequestDelegate next, LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var url = _linkGenerator.GetPathByAction("ListProducts", "Store");

        httpContext.Response.ContentType = "text/plain";

        await httpContext.Response.WriteAsync($"Go to {url} to see our products.");
    }
}

Informations de référence sur les modèles de routageRoute template reference

Les jetons dans {} définissent les paramètres de routage qui sont liés si l’itinéraire est mis en correspondance.Tokens within {} define route parameters that are bound if the route is matched. Plusieurs paramètres de routage peuvent être définis dans un segment de routage, mais les paramètres de routage doivent être séparés par une valeur littérale.More than one route parameter can be defined in a route segment, but route parameters must be separated by a literal value. Par exemple {controller=Home}{action=Index} n’est pas une route valide, car il n’y a aucune valeur littérale entre {controller} et {action}.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Les paramètres d’itinéraire doivent avoir un nom et des attributs supplémentaires peuvent être spécifiés.Route parameters must have a name and may have additional attributes specified.

Un texte littéral autre que les paramètres de routage (par exemple, {id}) et le séparateur de chemin / doit correspondre au texte présent dans l’URL.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. La correspondance de texte ne respecte pas la casse et est basée sur la représentation décodée du chemin d’accès de l’URL.Text matching is case-insensitive and based on the decoded representation of the URL's path. Pour correspondre à un délimiteur de paramètre d’itinéraire littéral { ou } , échappez le délimiteur en répétant le caractère.To match a literal route parameter delimiter { or }, escape the delimiter by repeating the character. Par exemple {{ }} , ou.For example {{ or }}.

Astérisque * ou double astérisque ** :Asterisk * or double asterisk **:

  • Peut être utilisé comme préfixe d’un paramètre d’itinéraire pour effectuer une liaison au reste de l’URI.Can be used as a prefix to a route parameter to bind to the rest of the URI.
  • Sont appelés paramètres catch-all .Are called a catch-all parameters. Par exemple, blog/{**slug}:For example, blog/{**slug}:
    • Correspond à n’importe quel URI commençant par /blog et dont la valeur est après.Matches any URI that starts with /blog and has any value following it.
    • La valeur suivante /blog est assignée à la valeur de route Slug .The value following /blog is assigned to the slug route value.

Avertissement

Un paramètre catch-all peut faire correspondre les itinéraires de manière incorrecte en raison d’un bogue dans le routage.A catch-all parameter may match routes incorrectly due to a bug in routing. Les applications affectées par ce bogue présentent les caractéristiques suivantes :Apps impacted by this bug have the following characteristics:

  • Un itinéraire de rattrapage, par exemple,{**slug}"A catch-all route, for example, {**slug}"
  • L’itinéraire catch-all ne parvient pas à faire correspondre les demandes auxquelles il doit correspondre.The catch-all route fails to match requests it should match.
  • La suppression d’autres itinéraires rend le fonctionnement de l’itinéraire de rattrapage.Removing other routes makes catch-all route start working.

Consultez les bogues GitHub 18677 et 16579 pour obtenir des exemples de cas qui rencontrent ce bogue.See GitHub bugs 18677 and 16579 for example cases that hit this bug.

Un correctif d’abonnement pour ce bogue est contenu dans .net Core 3.1.301 SDK et versions ultérieures.An opt-in fix for this bug is contained in .NET Core 3.1.301 SDK and later. Le code suivant définit un commutateur interne qui corrige ce bogue :The following code sets an internal switch that fixes this bug:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Les paramètres fourre-tout peuvent également établir une correspondance avec la chaîne vide.Catch-all parameters can also match the empty string.

Le paramètre Catch-All échappe les caractères appropriés lorsque l’itinéraire est utilisé pour générer une URL, y compris les caractères de séparation de chemin / .The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator / characters. Par exemple, la route foo/{*path} avec les valeurs de route { path = "my/path" } génère foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Notez la barre oblique d’échappement.Note the escaped forward slash. Pour les séparateurs de chemin aller-retour, utilisez le préfixe de paramètre de routage **.To round-trip path separator characters, use the ** route parameter prefix. La route foo/{**path} avec { path = "my/path" } génère foo/my/path.The route foo/{**path} with { path = "my/path" } generates foo/my/path.

Les modèles d’URL qui tentent de capturer un nom de fichier avec une extension de fichier facultative doivent faire l’objet de considérations supplémentaires.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Prenez par exemple le modèle files/{filename}.{ext?}.For example, consider the template files/{filename}.{ext?}. Quand des valeurs existent à la fois pour filename et pour ext, les deux valeurs sont renseignées.When values for both filename and ext exist, both values are populated. Si seule une valeur filename existe dans l’URL, l’itinéraire correspond, car la fin . est facultative.If only a value for filename exists in the URL, the route matches because the trailing . is optional. Les URL suivantes correspondent à cette route :The following URLs match this route:

  • /files/myFile.txt
  • /files/myFile

Les paramètres de route peuvent avoir des valeurs par défaut, désignées en spécifiant la valeur par défaut après le nom du paramètre, séparée par un signe égal (=).Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Par exemple, {controller=Home} définit Home comme valeur par défaut de controller.For example, {controller=Home} defines Home as the default value for controller. La valeur par défaut est utilisée si aucune valeur n’est présente dans l’URL pour le paramètre.The default value is used if no value is present in the URL for the parameter. Les paramètres de routage sont rendus facultatifs en ajoutant un point d’interrogation ( ? ) à la fin du nom du paramètre.Route parameters are made optional by appending a question mark (?) to the end of the parameter name. Par exemple : id?.For example, id?. La différence entre les valeurs facultatives et les paramètres d’itinéraire par défaut est la suivante :The difference between optional values and default route parameters is:

  • Un paramètre d’itinéraire avec une valeur par défaut produit toujours une valeur.A route parameter with a default value always produces a value.
  • Un paramètre facultatif a une valeur uniquement lorsqu’une valeur est fournie par l’URL de la requête.An optional parameter has a value only when a value is provided by the request URL.

Les paramètres de route peuvent avoir des contraintes, qui doivent correspondre à la valeur de route liée à partir de l’URL.Route parameters may have constraints that must match the route value bound from the URL. Ajout : d’un nom de contrainte après le nom du paramètre d’itinéraire spécifie une contrainte Inline sur un paramètre d’itinéraire.Adding : and constraint name after the route parameter name specifies an inline constraint on a route parameter. Si la contrainte exige des arguments, ils sont fournis entre parenthèses (...) après le nom de la contrainte.If the constraint requires arguments, they're enclosed in parentheses (...) after the constraint name. Vous pouvez spécifier plusieurs contraintes Inline en ajoutant un autre : nom de contrainte et.Multiple inline constraints can be specified by appending another : and constraint name.

Le nom de la contrainte et les arguments sont passés au service IInlineConstraintResolver pour créer une instance de IRouteConstraint à utiliser dans le traitement des URL.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. Par exemple, le modèle de routage blog/{article:minlength(10)} spécifie une contrainte minlength avec l’argument 10.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Pour plus d’informations sur les contraintes de route et pour obtenir la liste des contraintes fournies par le framework, consultez la section Informations de référence sur les contraintes de route.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Les paramètres de routage peuvent également avoir des transformateurs de paramètre.Route parameters may also have parameter transformers. Les transformateurs de paramètres transforment la valeur d’un paramètre lors de la génération de liens et d’actions et de pages correspondantes en URL.Parameter transformers transform a parameter's value when generating links and matching actions and pages to URLs. Comme pour les contraintes, les transformateurs de paramètres peuvent être ajoutés Inline à un paramètre d’itinéraire en ajoutant un : nom de transformateur et après le nom du paramètre d’itinéraire.Like constraints, parameter transformers can be added inline to a route parameter by adding a : and transformer name after the route parameter name. Par exemple, le modèle de routage blog/{article:slugify} spécifie un transformateur slugify.For example, the route template blog/{article:slugify} specifies a slugify transformer. Pour plus d’informations sur les transformateurs de paramètre, consultez la section Informations de référence sur les transformateurs de paramètre.For more information on parameter transformers, see the Parameter transformer reference section.

Le tableau suivant montre des exemples de modèles de routage et leur comportement :The following table demonstrates example route templates and their behavior:

Modèle de routageRoute Template Exemple d’URI en correspondanceExample Matching URI URI de la requête…The request URI…
hello /hello Correspond seulement au chemin unique /hello.Only matches the single path /hello.
{Page=Home} / Correspond à Page et le définit sur Home.Matches and sets Page to Home.
{Page=Home} /Contact Correspond à Page et le définit sur Contact.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Mappe au contrôleur Products et à l’action List.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Correspond au Products contrôleur et à l' Details action avec la id valeur 123.Maps to the Products controller and Details action withid set to 123.
{controller=Home}/{action=Index}/{id?} / Correspond au Home contrôleur et à la Index méthode.Maps to the Home controller and Index method. id est ignoré.id is ignored.
{controller=Home}/{action=Index}/{id?} /Products Correspond au Products contrôleur et à la Index méthode.Maps to the Products controller and Index method. id est ignoré.id is ignored.

L’utilisation d’un modèle est généralement l’approche la plus simple pour le routage.Using a template is generally the simplest approach to routing. Il est également possible de spécifier des contraintes et des valeurs par défaut hors du modèle de routage.Constraints and defaults can also be specified outside the route template.

Segments complexesComplex segments

Les segments complexes sont traités en faisant correspondre les délimiteurs littéraux de droite à gauche d’une façon non gourmande .Complex segments are processed by matching up literal delimiters from right to left in a non-greedy way. Par exemple, [Route("/a{b}c{d}")] est un segment complexe.For example, [Route("/a{b}c{d}")] is a complex segment. Les segments complexes fonctionnent d’une manière particulière qui doit être comprise pour pouvoir les utiliser avec succès.Complex segments work in a particular way that must be understood to use them successfully. L’exemple de cette section montre pourquoi les segments complexes ne fonctionnent vraiment que si le texte du délimiteur ne s’affiche pas dans les valeurs de paramètre.The example in this section demonstrates why complex segments only really work well when the delimiter text doesn't appear inside the parameter values. L’utilisation d’une expression régulière , puis l’extraction manuelle des valeurs est nécessaire pour les cas plus complexes.Using a regex and then manually extracting the values is needed for more complex cases.

Avertissement

Lorsque vous System.Text.RegularExpressions utilisez pour traiter une entrée non fiable, transmettez un délai d’attente.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Un utilisateur malveillant peut fournir une entrée RegularExpressions pour provoquer une attaque par déni de service.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core les API d’infrastructure RegularExpressions qui utilisent passent un délai d’expiration.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Il s’agit d’un résumé des étapes que le routage effectue avec le modèle /a{b}c{d} et le chemin d’URL /abcd .This is a summary of the steps that routing performs with the template /a{b}c{d} and the URL path /abcd. |Est utilisé pour aider à visualiser le fonctionnement de l’algorithme :The | is used to help visualize how the algorithm works:

  • Le premier littéral, de droite à gauche, est c .The first literal, right to left, is c. Par conséquent, la /abcd recherche s’effectue à partir de Right et trouve /ab|c|d .So /abcd is searched from right and finds /ab|c|d.
  • Tout ce qui se trouve à droite ( d ) est maintenant mis en correspondance avec le paramètre d’itinéraire {d} .Everything to the right (d) is now matched to the route parameter {d}.
  • Le littéral suivant, de droite à gauche, est a .The next literal, right to left, is a. Dans ce cas /ab|c|d , la recherche commence là où nous l’avons laissée, puis a est trouvé /|a|b|c|d .So /ab|c|d is searched starting where we left off, then a is found /|a|b|c|d.
  • La valeur à droite ( b ) est désormais mise en correspondance avec le paramètre d’itinéraire {b} .The value to the right (b) is now matched to the route parameter {b}.
  • Il n’y a pas de texte restant et aucun modèle de route restant, donc il s’agit d’une correspondance.There is no remaining text and no remaining route template, so this is a match.

Voici un exemple de cas négatif utilisant le même modèle /a{b}c{d} et le chemin d’URL /aabcd .Here's an example of a negative case using the same template /a{b}c{d} and the URL path /aabcd. Le | est utilisé pour aider à visualiser le fonctionnement de l’algorithme.The | is used to help visualize how the algorithm works. Ce cas n’est pas une correspondance, qui est expliquée par le même algorithme :This case isn't a match, which is explained by the same algorithm:

  • Le premier littéral, de droite à gauche, est c .The first literal, right to left, is c. Par conséquent, la /aabcd recherche s’effectue à partir de Right et trouve /aab|c|d .So /aabcd is searched from right and finds /aab|c|d.
  • Tout ce qui se trouve à droite ( d ) est maintenant mis en correspondance avec le paramètre d’itinéraire {d} .Everything to the right (d) is now matched to the route parameter {d}.
  • Le littéral suivant, de droite à gauche, est a .The next literal, right to left, is a. Dans ce cas /aab|c|d , la recherche commence là où nous l’avons laissée, puis a est trouvé /a|a|b|c|d .So /aab|c|d is searched starting where we left off, then a is found /a|a|b|c|d.
  • La valeur à droite ( b ) est désormais mise en correspondance avec le paramètre d’itinéraire {b} .The value to the right (b) is now matched to the route parameter {b}.
  • À ce stade, il reste du texte a , mais l’algorithme n’a plus de modèle de routage à analyser, donc ce n’est pas une correspondance.At this point there is remaining text a, but the algorithm has run out of route template to parse, so this is not a match.

Étant donné que l’algorithme de correspondance n’est pas gourmand:Since the matching algorithm is non-greedy:

  • Il correspond à la plus petite quantité de texte possible dans chaque étape.It matches the smallest amount of text possible in each step.
  • Tout cas où la valeur de délimiteur apparaît à l’intérieur des valeurs de paramètre ne correspond pas.Any case where the delimiter value appears inside the parameter values results in not matching.

Les expressions régulières permettent de mieux contrôler le comportement de leur correspondance.Regular expressions provide much more control over their matching behavior.

La correspondance gourmande, également connue comme correspondance tardive, correspond à la plus grande chaîne possible.Greedy matching, also know as lazy matching, matches the largest possible string. Non gourmand correspond à la plus petite chaîne possible.Non-greedy matches the smallest possible string.

Informations de référence sur les contraintes de routageRoute constraint reference

Les contraintes de route s’exécutent quand une correspondance s’est produite pour l’URL entrante, et le chemin de l’URL est tokenisé en valeurs de route.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. En général, les contraintes de routage inspectent la valeur de routage associée via le modèle de routage et font une décision true ou false indiquant si la valeur est acceptable ou non.Route constraints generally inspect the route value associated via the route template and make a true or false decision about whether the value is acceptable. Certaines contraintes de routage utilisent des données hors de la valeur de route pour déterminer si la requête peut être routée.Some route constraints use data outside the route value to consider whether the request can be routed. Par exemple, HttpMethodRouteConstraint peut accepter ou rejeter une requête en fonction de son verbe HTTP.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Les contraintes sont utilisées dans le routage des requêtes et la génération des liens.Constraints are used in routing requests and link generation.

Avertissement

N’utilisez pas de contraintes pour la validation des entrées.Don't use constraints for input validation. Si des contraintes sont utilisées pour la validation d’entrée, une entrée non valide entraîne une 404 réponse introuvable.If constraints are used for input validation, invalid input results in a 404 Not Found response. Une entrée non valide doit générer une 400 Demande incorrecte avec un message d’erreur approprié.Invalid input should produce a 400 Bad Request with an appropriate error message. Les contraintes de route sont utilisées pour lever l’ambiguïté entre des routes similaires, et non pas pour valider les entrées d’une route particulière.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

Le tableau suivant montre des exemples de contraintes de routage et leur comportement attendu :The following table demonstrates example route constraints and their expected behavior:

contrainteconstraint  ExempleExample Exemples de correspondancesExample Matches NotesNotes
int {id:int} 123456789, -123456789123456789, -123456789 Correspond à n’importe quel entierMatches any integer
bool {active:bool} true, FALSEtrue, FALSE Correspond à true ou false .Matches true or false. Non-respect de la casseCase-insensitive
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Correspond à une DateTime valeur valide dans la culture dite indifférente.Matches a valid DateTime value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Correspond à une decimal valeur valide dans la culture dite indifférente.Matches a valid decimal value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une double valeur valide dans la culture dite indifférente.Matches a valid double value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une float valeur valide dans la culture dite indifférente.Matches a valid float value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Correspond à une valeur Guid valideMatches a valid Guid value
long {ticks:long} 123456789, -123456789123456789, -123456789 Correspond à une valeur long valideMatches a valid long value
minlength(value) {username:minlength(4)} Rick La chaîne doit comporter au moins 4 caractèresString must be at least 4 characters
maxlength(value) {filename:maxlength(8)} MyFile La chaîne ne doit pas comporter plus de 8 caractèresString must be no more than 8 characters
length(length) {filename:length(12)} somefile.txt La chaîne doit comporter exactement 12 caractèresString must be exactly 12 characters long
length(min,max) {filename:length(8,16)} somefile.txt La chaîne doit comporter au moins 8 caractères et pas plus de 16 caractèresString must be at least 8 and no more than 16 characters long
min(value) {age:min(18)} 19 La valeur entière doit être au moins égale à 18Integer value must be at least 18
max(value) {age:max(120)} 91 La valeur entière ne doit pas être supérieure à 120Integer value must be no more than 120
range(min,max) {age:range(18,120)} 91 La valeur entière doit être au moins égale à 18 mais ne doit pas être supérieure à 120Integer value must be at least 18 but no more than 120
alpha {name:alpha} Rick La chaîne doit comporter un ou plusieurs caractères alphabétiques et ne respecte pas la a - z casse.String must consist of one or more alphabetical characters, a-z and case-insensitive.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 La chaîne doit correspondre à l’expression régulière.String must match the regular expression. Consultez les conseils relatifs à la définition d’une expression régulière.See tips about defining a regular expression.
required {name:required} Rick Utilisé pour garantir qu’une valeur autre qu’un paramètre est présente pendant la génération de l’URLUsed to enforce that a non-parameter value is present during URL generation

Avertissement

Lorsque vous System.Text.RegularExpressions utilisez pour traiter une entrée non fiable, transmettez un délai d’attente.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Un utilisateur malveillant peut fournir une entrée RegularExpressions pour provoquer une attaque par déni de service.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core les API d’infrastructure RegularExpressions qui utilisent passent un délai d’expiration.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Plusieurs contraintes séparées par des points-virgules peuvent être appliquées à un seul paramètre.Multiple, colon delimited constraints can be applied to a single parameter. Par exemple, la contrainte suivante limite un paramètre à une valeur entière supérieure ou égale à 1 :For example, the following constraint restricts a parameter to an integer value of 1 or greater:

[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

Avertissement

Les contraintes de routage qui vérifient l’URL et sont converties en un type CLR utilisent toujours la culture dite indifférente.Route constraints that verify the URL and are converted to a CLR type always use the invariant culture. Par exemple, la conversion vers le type CLR int ou DateTime .For example, conversion to the CLR type int or DateTime. Ces contraintes supposent que l’URL n’est pas localisable.These constraints assume that the URL is not localizable. Les contraintes de routage fournies par le framework ne modifient pas les valeurs stockées dans les valeurs de route.The framework-provided route constraints don't modify the values stored in route values. Toutes les valeurs de route analysées à partir de l’URL sont stockées sous forme de chaînes.All route values parsed from the URL are stored as strings. Par exemple, la contrainte float tente de convertir la valeur de route en valeur float, mais la valeur convertie est utilisée uniquement pour vérifier qu’elle peut être convertie en valeur float.For example, the float constraint attempts to convert the route value to a float, but the converted value is used only to verify it can be converted to a float.

Expressions régulières dans les contraintesRegular expressions in constraints

Avertissement

Lorsque vous System.Text.RegularExpressions utilisez pour traiter une entrée non fiable, transmettez un délai d’attente.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Un utilisateur malveillant peut fournir une entrée RegularExpressions pour provoquer une attaque par déni de service.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core les API d’infrastructure RegularExpressions qui utilisent passent un délai d’expiration.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Les expressions régulières peuvent être spécifiées en tant que contraintes Inline à l’aide de la regex(...) contrainte d’itinéraire.Regular expressions can be specified as inline constraints using the regex(...) route constraint. Les méthodes de la MapControllerRoute famille acceptent également un littéral d’objet de contraintes.Methods in the MapControllerRoute family also accept an object literal of constraints. Si ce formulaire est utilisé, les valeurs de chaîne sont interprétées comme des expressions régulières.If that form is used, string values are interpreted as regular expressions.

Le code suivant utilise une contrainte Regex inline :The following code uses an inline regex constraint:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
        context => 
        {
            return context.Response.WriteAsync("inline-constraint match");
        });
 });

Le code suivant utilise un littéral d’objet pour spécifier une contrainte Regex :The following code uses an object literal to specify a regex constraint:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "people",
        pattern: "People/{ssn}",
        constraints: new { ssn = "^\\d{3}-\\d{2}-\\d{4}$", },
        defaults: new { controller = "People", action = "List", });
});

Le framework ASP.NET Core ajoute RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant au constructeur d’expression régulière.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Pour obtenir une description de ces membres, consultez RegexOptions.See RegexOptions for a description of these members.

Les expressions régulières utilisent des délimiteurs et des jetons similaires à ceux utilisés par le routage et le langage C#.Regular expressions use delimiters and tokens similar to those used by routing and the C# language. Les jetons d’expression régulière doivent être placés dans une séquence d’échappement.Regular expression tokens must be escaped. Pour utiliser l’expression régulière ^\d{3}-\d{2}-\d{4}$ dans une contrainte incluse, utilisez l’une des méthodes suivantes :To use the regular expression ^\d{3}-\d{2}-\d{4}$ in an inline constraint, use one of the following:

  • Remplacez les \ caractères fournis dans la chaîne en tant que \\ caractères dans le fichier source C# pour échapper le caractère d’échappement de la \ chaîne.Replace \ characters provided in the string as \\ characters in the C# source file in order to escape the \ string escape character.
  • Littéraux de chaîne Verbatim.Verbatim string literals.

Pour échapper les caractères de délimiteur de paramètre de routage { ,,,, } [ ] doublez les caractères dans l’expression, par exemple,,, {{ }} [[ , ]] .To escape routing parameter delimiter characters {, }, [, ], double the characters in the expression, for example, {{, }}, [[, ]]. Le tableau suivant montre une expression régulière et sa version échappée :The following table shows a regular expression and its escaped version:

Expression régulièreRegular expression Expression régulière placée dans une séquence d’échappementEscaped regular expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Les expressions régulières utilisées dans le routage commencent souvent par le ^ caractère et correspondent à la position de départ de la chaîne.Regular expressions used in routing often start with the ^ character and match the starting position of the string. Les expressions se terminent souvent par le $ caractère et correspondent à la fin de la chaîne.The expressions often end with the $ character and match the end of the string. Les ^ $ caractères et garantissent que l’expression régulière correspond à l’intégralité de la valeur du paramètre d’itinéraire.The ^ and $ characters ensure that the regular expression matches the entire route parameter value. Sans les ^ $ caractères et, l’expression régulière correspond à toute sous-chaîne de la chaîne, ce qui est souvent indésirable.Without the ^ and $ characters, the regular expression matches any substring within the string, which is often undesirable. Le tableau suivant fournit des exemples et explique pourquoi ils correspondent ou ne parviennent pas à faire correspondre :The following table provides examples and explains why they match or fail to match:

ExpressionExpression StringString CorrespondMatch CommentaireComment
[a-z]{2} hellohello OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} 123abc456123abc456 OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} mzmz OuiYes Correspondance avec l’expressionMatches expression
[a-z]{2} MZMZ OuiYes Non-respect de la casseNot case sensitive
^[a-z]{2}$ hellohello NonNo Voir ^ et $ ci-dessusSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NonNo Voir ^ et $ ci-dessusSee ^ and $ above

Pour plus d’informations sur la syntaxe des expressions régulières, consultez Expressions régulières du .NET Framework.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Pour contraindre un paramètre à un ensemble connu de valeurs possibles, utilisez une expression régulière.To constrain a parameter to a known set of possible values, use a regular expression. Par exemple, {action:regex(^(list|get|create)$)} établit une correspondance avec la valeur de route action uniquement pour list, get ou create.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Si elle est passée dans le dictionnaire de contraintes, la chaîne ^(list|get|create)$ est équivalente.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Les contraintes passées dans le dictionnaire de contraintes qui ne correspondent pas à l’une des contraintes connues sont également traitées comme des expressions régulières.Constraints that are passed in the constraints dictionary that don't match one of the known constraints are also treated as regular expressions. Les contraintes passées dans un modèle qui ne correspondent pas à l’une des contraintes connues ne sont pas traitées comme des expressions régulières.Constraints that are passed within a template that don't match one of the known constraints are not treated as regular expressions.

Contraintes d’itinéraire personnaliséesCustom route constraints

Vous pouvez créer des contraintes de routage personnalisées en implémentant l' IRouteConstraint interface.Custom route constraints can be created by implementing the IRouteConstraint interface. L' IRouteConstraint interface contient Match , qui retourne true si la contrainte est satisfaite et dans le false cas contraire.The IRouteConstraint interface contains Match, which returns true if the constraint is satisfied and false otherwise.

Les contraintes de routage personnalisées sont rarement nécessaires.Custom route constraints are rarely needed. Avant d’implémenter une contrainte d’itinéraire personnalisée, envisagez d’autres méthodes, telles que la liaison de modèle.Before implementing a custom route constraint, consider alternatives, such as model binding.

Le dossier ASP.NET Core Constraints fournit de bons exemples de création de contraintes.The ASP.NET Core Constraints folder provides good examples of creating a constraints. Par exemple, GuidRouteConstraint.For example, GuidRouteConstraint.

Pour utiliser un personnalisé IRouteConstraint , le type de contrainte d’itinéraire doit être enregistré avec l’application ConstraintMap dans le conteneur de service.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the service container. Un ConstraintMap est un dictionnaire qui mappe les clés de contrainte d’itinéraire aux implémentations IRouteConstraint qui valident ces contraintes.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Le ConstraintMap d’une application peut être mis à jour dans Startup.ConfigureServices dans le cadre d’un appel services.AddRouting ou en configurant RouteOptions directement avec services.Configure<RouteOptions>.An app's ConstraintMap can be updated in Startup.ConfigureServices either as part of a services.AddRouting call or by configuring RouteOptions directly with services.Configure<RouteOptions>. Par exemple :For example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddRouting(options =>
    {
        options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
    });
}

La contrainte précédente est appliquée dans le code suivant :The preceding constraint is applied in the following code:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    // GET /api/test/3
    [HttpGet("{id:customName}")]
    public IActionResult Get(string id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // GET /api/test/my/3
    [HttpGet("my/{id:customName}")]
    public IActionResult Get(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

MyDisplayRouteInfo est fourni par le package NuGet Rick. docs. Samples. RouteInfo et affiche des informations sur l’itinéraire.MyDisplayRouteInfo is provided by the Rick.Docs.Samples.RouteInfo NuGet package and displays route information.

L’implémentation de MyCustomConstraint empêche d' 0 être appliquée à un paramètre d’itinéraire :The implementation of MyCustomConstraint prevents 0 being applied to a route parameter:

class MyCustomConstraint : IRouteConstraint
{
    private Regex _regex;

    public MyCustomConstraint()
    {
        _regex = new Regex(@"^[1-9]*$",
                            RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
                            TimeSpan.FromMilliseconds(100));
    }
    public bool Match(HttpContext httpContext, IRouter route, string routeKey,
                      RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (values.TryGetValue(routeKey, out object value))
        {
            var parameterValueString = Convert.ToString(value,
                                                        CultureInfo.InvariantCulture);
            if (parameterValueString == null)
            {
                return false;
            }

            return _regex.IsMatch(parameterValueString);
        }

        return false;
    }
}

Avertissement

Lorsque vous System.Text.RegularExpressions utilisez pour traiter une entrée non fiable, transmettez un délai d’attente.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Un utilisateur malveillant peut fournir une entrée RegularExpressions pour provoquer une attaque par déni de service.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core les API d’infrastructure RegularExpressions qui utilisent passent un délai d’expiration.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Le code précédent :The preceding code:

  • Empêche 0 dans le {id} segment de l’itinéraire.Prevents 0 in the {id} segment of the route.
  • Est présenté pour fournir un exemple de base de l’implémentation d’une contrainte personnalisée.Is shown to provide a basic example of implementing a custom constraint. Il ne doit pas être utilisé dans une application de production.It should not be used in a production app.

Le code suivant est une meilleure approche pour empêcher un id contenant un qui est 0 traité :The following code is a better approach to preventing an id containing a 0 from being processed:

[HttpGet("{id}")]
public IActionResult Get(string id)
{
    if (id.Contains('0'))
    {
        return StatusCode(StatusCodes.Status406NotAcceptable);
    }

    return ControllerContext.MyDisplayRouteInfo(id);
}

Le code précédent présente les avantages suivants par rapport à l' MyCustomConstraint approche :The preceding code has the following advantages over the MyCustomConstraint approach:

  • Elle ne nécessite pas de contrainte personnalisée.It doesn't require a custom constraint.
  • Elle retourne une erreur plus descriptive lorsque le paramètre d’itinéraire contient 0 .It returns a more descriptive error when the route parameter includes 0.

Informations de référence sur le transformateur de paramètreParameter transformer reference

Transformateurs de paramètre :Parameter transformers:

Par exemple, un transformateur de paramètre slugify personnalisé dans le modèle d’itinéraire blog\{article:slugify} avec Url.Action(new { article = "MyTestArticle" }) génère blog\my-test-article.For example, a custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article.

Tenez compte de l' IOutboundParameterTransformer implémentation suivante :Consider the following IOutboundParameterTransformer implementation:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        if (value == null) { return null; }

        return Regex.Replace(value.ToString(), 
                             "([a-z])([A-Z])",
                             "$1-$2",
                             RegexOptions.CultureInvariant,
                             TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
    }
}

Pour utiliser un transformateur de paramètre dans un modèle d’itinéraire, configurez-le à l’aide ConstraintMap de dans Startup.ConfigureServices :To use a parameter transformer in a route pattern, configure it using ConstraintMap in Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddRouting(options =>
    {
        options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    });
}

L’infrastructure de ASP.NET Core utilise des transformateurs de paramètre pour transformer l’URI dans lequel un point de terminaison est résolu.The ASP.NET Core framework uses parameter transformers to transform the URI where an endpoint resolves. Par exemple, les transformateurs de paramètres transforment les valeurs d’itinéraire utilisées pour faire correspondre un area ,, controller action et page .For example, parameter transformers transform the route values used to match an area, controller, action, and page.

routes.MapControllerRoute(
    name: "default",
    template: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

Avec le modèle de route précédent, l’action SubscriptionManagementController.GetAll est mise en correspondance avec l’URI /subscription-management/get-all .With the preceding route template, the action SubscriptionManagementController.GetAll is matched with the URI /subscription-management/get-all. Un transformateur de paramètre ne modifie pas les valeurs de routage utilisées pour générer un lien.A parameter transformer doesn't change the route values used to generate a link. Par exemple, Url.Action("GetAll", "SubscriptionManagement") produit /subscription-management/get-all.For example, Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core fournit des conventions d’API pour l’utilisation de transformateurs de paramètres avec des itinéraires générés :ASP.NET Core provides API conventions for using parameter transformers with generated routes:

Informations de référence sur la génération d’URLURL generation reference

Cette section contient une référence pour l’algorithme implémenté par la génération d’URL.This section contains a reference for the algorithm implemented by URL generation. Dans la pratique, la plupart des exemples complexes de génération d’URL utilisent des contrôleurs ou des Razor pages.In practice, most complex examples of URL generation use controllers or Razor Pages. Pour plus d’informations, consultez routage dans les contrôleurs .See routing in controllers for additional information.

Le processus de génération d’URL commence par un appel à LinkGenerator. GetPathByAddress ou à une méthode similaire.The URL generation process begins with a call to LinkGenerator.GetPathByAddress or a similar method. La méthode est fournie avec une adresse, un ensemble de valeurs d’itinéraire et éventuellement des informations sur la requête actuelle à partir de HttpContext .The method is provided with an address, a set of route values, and optionally information about the current request from HttpContext.

La première étape consiste à utiliser l’adresse pour résoudre un jeu de points de terminaison candidats à l’aide d’un IEndpointAddressScheme<TAddress> qui correspond au type de l’adresse.The first step is to use the address to resolve a set of candidate endpoints using an IEndpointAddressScheme<TAddress> that matches the address's type.

Une fois l’ensemble de candidats trouvé par le schéma d’adresse, les points de terminaison sont triés et traités de manière itérative jusqu’à ce qu’une opération de génération d’URL aboutisse.Once of set of candidates is found by the address scheme, the endpoints are ordered and processed iteratively until a URL generation operation succeeds. La génération d’URL ne vérifie pas les ambiguïtés, le premier résultat retourné est le résultat final.URL generation does not check for ambiguities, the first result returned is the final result.

Résolution des problèmes de génération d’URL avec journalisationTroubleshooting URL generation with logging

La première étape de la résolution des problèmes liés à la génération d’URL consiste à définir le niveau de journalisation Microsoft.AspNetCore.Routing sur TRACE .The first step in troubleshooting URL generation is setting the logging level of Microsoft.AspNetCore.Routing to TRACE. LinkGenerator journalise de nombreux détails sur son traitement, ce qui peut être utile pour résoudre les problèmes.LinkGenerator logs many details about its processing which can be useful to troubleshoot problems.

Pour plus d’informations sur la génération d’URL, consultez référence de génération d’URL .See URL generation reference for details on URL generation.

AdressesAddresses

Les adresses sont le concept dans la génération d’URL utilisé pour lier un appel dans le générateur de liens à un jeu de points de terminaison candidats.Addresses are the concept in URL generation used to bind a call into the link generator to a set of candidate endpoints.

Les adresses sont un concept extensible qui est fourni avec deux implémentations par défaut :Addresses are an extensible concept that come with two implementations by default:

  • Utilisation du nom de point de terminaison ( string ) comme adresse :Using endpoint name (string) as the address:
    • Fournit des fonctionnalités similaires au nom d’itinéraire de MVC.Provides similar functionality to MVC's route name.
    • Utilise le IEndpointNameMetadata type de métadonnées.Uses the IEndpointNameMetadata metadata type.
    • Résout la chaîne fournie par rapport aux métadonnées de tous les points de terminaison inscrits.Resolves the provided string against the metadata of all registered endpoints.
    • Lève une exception au démarrage si plusieurs points de terminaison utilisent le même nom.Throws an exception on startup if multiple endpoints use the same name.
    • Recommandé pour une utilisation à usage général en dehors des contrôleurs et des Razor pages.Recommended for general-purpose use outside of controllers and Razor Pages.
  • Utilisation des valeurs de route ( RouteValuesAddress ) comme adresse :Using route values (RouteValuesAddress) as the address:
    • Fournit des fonctionnalités similaires aux contrôleurs et aux Razor pages génération d’URL héritées.Provides similar functionality to controllers and Razor Pages legacy URL generation.
    • Très complexe à étendre et à déboguer.Very complex to extend and debug.
    • Fournit l’implémentation utilisée par IUrlHelper , les tag helpers, les applications auxiliaires html, les résultats d’action, etc.Provides the implementation used by IUrlHelper, Tag Helpers, HTML Helpers, Action Results, etc.

Le rôle du schéma d’adresse consiste à effectuer l’association entre l’adresse et les points de terminaison correspondants à l’aide de critères arbitraires :The role of the address scheme is to make the association between the address and matching endpoints by arbitrary criteria:

  • Le modèle de nom de point de terminaison effectue une recherche de dictionnaire de base.The endpoint name scheme performs a basic dictionary lookup.
  • Le schéma de valeurs d’itinéraire a un meilleur sous-ensemble complexe de l’algorithme Set.The route values scheme has a complex best subset of set algorithm.

Valeurs ambiantes et valeurs explicitesAmbient values and explicit values

À partir de la requête actuelle, le routage accède aux valeurs d’itinéraire de la requête actuelle HttpContext.Request.RouteValues .From the current request, routing accesses the route values of the current request HttpContext.Request.RouteValues. Les valeurs associées à la requête actuelle sont appelées valeurs ambiantes.The values associated with the current request are referred to as the ambient values. Pour des raisons de clarté, la documentation fait référence aux valeurs de route transmises aux méthodes en tant que valeurs explicites.For the purpose of clarity, the documentation refers to the route values passed in to methods as explicit values.

L’exemple suivant montre des valeurs ambiantes et des valeurs explicites.The following example shows ambient values and explicit values. Il fournit des valeurs ambiantes de la demande actuelle et des valeurs explicites : { id = 17, } :It provides ambient values from the current request and explicit values: { id = 17, }:

public class WidgetController : Controller
{
    private readonly LinkGenerator _linkGenerator;

    public WidgetController(LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public IActionResult Index()
    {
        var url = _linkGenerator.GetPathByAction(HttpContext,
                                                 null, null,
                                                 new { id = 17, });
        return Content(url);
    }

Le code précédent :The preceding code:

Le code suivant ne fournit aucune valeur ambiante ni valeur explicite : { controller = "Home", action = "Subscribe", id = 17, } :The following code provides no ambient values and explicit values: { controller = "Home", action = "Subscribe", id = 17, }:

public IActionResult Index2()
{
    var url = _linkGenerator.GetPathByAction("Subscribe", "Home",
                                             new { id = 17, });
    return Content(url);
}

La méthode précédente retourne /Home/Subscribe/17The preceding method returns /Home/Subscribe/17

Le code suivant dans le WidgetController retourne /Widget/Subscribe/17 :The following code in the WidgetController returns /Widget/Subscribe/17:

var url = _linkGenerator.GetPathByAction("Subscribe", null,
                                         new { id = 17, });

Le code suivant fournit le contrôleur à partir des valeurs ambiantes dans la requête actuelle et les valeurs explicites : { action = "Edit", id = 17, } :The following code provides the controller from ambient values in the current request and explicit values: { action = "Edit", id = 17, }:

public class GadgetController : Controller
{
    public IActionResult Index()
    {
        var url = Url.Action("Edit", new { id = 17, });
        return Content(url);
    }

Dans le code précédent :In the preceding code:

  • /Gadget/Edit/17 est retourné./Gadget/Edit/17 is returned.
  • Url Obtient IUrlHelper .Url gets the IUrlHelper.
  • Action
    génère une URL avec un chemin d’accès absolu pour une méthode d’action.generates a URL with an absolute path for an action method. L’URL contient le action nom et les route valeurs spécifiés.The URL contains the specified action name and route values.

Le code suivant fournit des valeurs ambiantes de la demande actuelle et des valeurs explicites : { page = "./Edit, id = 17, } :The following code provides ambient values from the current request and explicit values: { page = "./Edit, id = 17, }:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var url = Url.Page("./Edit", new { id = 17, });
        ViewData["URL"] = url;
    }
}

Le code précédent affecte la url valeur /Edit/17 lorsque la Razor page Modifier contient la directive de page suivante :The preceding code sets url to /Edit/17 when the Edit Razor Page contains the following page directive:

@page "{id:int}"

Si la page de modification ne contient pas le "{id:int}" modèle de routage, url est /Edit?id=17 .If the Edit page doesn't contain the "{id:int}" route template, url is /Edit?id=17.

Le comportement de MVC IUrlHelper ajoute une couche de complexité en plus des règles décrites ici :The behavior of MVC's IUrlHelper adds a layer of complexity in addition to the rules described here:

  • IUrlHelper fournit toujours les valeurs d’itinéraire de la requête actuelle comme valeurs ambiantes.IUrlHelper always provides the route values from the current request as ambient values.
  • IUrlHelper. action copie toujours les action valeurs actuelles et de controller routage en tant que valeurs explicites, sauf si elles sont remplacées par le développeur.IUrlHelper.Action always copies the current action and controller route values as explicit values unless overridden by the developer.
  • IUrlHelper. page copie toujours la page valeur de route actuelle en tant que valeur explicite, sauf si elle est substituée.IUrlHelper.Page always copies the current page route value as an explicit value unless overridden.
  • IUrlHelper.Page remplace toujours la handler valeur de route actuelle par null comme valeur explicite, sauf si elle est substituée.IUrlHelper.Page always overrides the current handler route value with null as an explicit values unless overridden.

Les utilisateurs sont souvent surpris par les détails de comportement des valeurs ambiantes, car MVC ne semble pas suivre ses propres règles.Users are often surprised by the behavioral details of ambient values, because MVC doesn't seem to follow its own rules. Pour des raisons d’historique et de compatibilité, certaines valeurs de route, telles que action ,, controller page et handler ont leur propre comportement spécial.For historical and compatibility reasons, certain route values such as action, controller, page, and handler have their own special-case behavior.

Les fonctionnalités équivalentes fournies par LinkGenerator.GetPathByAction et LinkGenerator.GetPathByPage dupliquent ces anomalies de IUrlHelper pour la compatibilité.The equivalent functionality provided by LinkGenerator.GetPathByAction and LinkGenerator.GetPathByPage duplicates these anomalies of IUrlHelper for compatibility.

Processus de génération d’URLURL generation process

Une fois que le jeu de points de terminaison candidats est trouvé, l’algorithme de génération d’URL :Once the set of candidate endpoints are found, the URL generation algorithm:

  • Traite les points de terminaison de manière itérative.Processes the endpoints iteratively.
  • Retourne le premier résultat réussi.Returns the first successful result.

La première étape de ce processus est appelée invalidationde la valeur de l’itinéraire.The first step in this process is called route value invalidation. L’invalidation de la valeur de routage est le processus par lequel le routage décide des valeurs d’itinéraire des valeurs ambiantes qui doivent être utilisées et qui doivent être ignorées.Route value invalidation is the process by which routing decides which route values from the ambient values should be used and which should be ignored. Chaque valeur ambiante est prise en compte et soit combinée avec les valeurs explicites, soit ignorée.Each ambient value is considered and either combined with the explicit values, or ignored.

La meilleure façon de réfléchir au rôle des valeurs ambiantes est qu’elles essaient d’enregistrer les développeurs d’applications qui tapent, dans certains cas courants.The best way to think about the role of ambient values is that they attempt to save application developers typing, in some common cases. Traditionnellement, les scénarios où les valeurs ambiantes sont utiles sont liés à MVC :Traditionally, the scenarios where ambient values are helpful are related to MVC:

  • Lors de la liaison à une autre action dans le même contrôleur, le nom du contrôleur n’a pas besoin d’être spécifié.When linking to another action in the same controller, the controller name doesn't need to be specified.
  • Lors de la liaison à un autre contrôleur dans la même zone, il n’est pas nécessaire de spécifier le nom de la zone.When linking to another controller in the same area, the area name doesn't need to be specified.
  • Lors de la liaison à la même méthode d’action, il n’est pas nécessaire de spécifier des valeurs de route.When linking to the same action method, route values don't need to be specified.
  • Lors de la liaison à une autre partie de l’application, vous ne souhaitez pas transférer les valeurs de route qui n’ont aucune signification dans cette partie de l’application.When linking to another part of the app, you don't want to carry over route values that have no meaning in that part of the app.

Les appels à LinkGenerator ou à IUrlHelper ce retour null sont généralement provoqués par la non-compréhension de l’invalidation de la valeur de l’itinéraire.Calls to LinkGenerator or IUrlHelper that return null are usually caused by not understanding route value invalidation. Résolvez les problèmes d’invalidation de valeur de routage en spécifiant explicitement plus de valeurs d’itinéraire pour voir si cela résout le problème.Troubleshoot route value invalidation by explicitly specifying more of the route values to see if that solves the problem.

L’invalidation de la valeur de routage fonctionne en partant du principe que le schéma d’URL de l’application est hiérarchique, avec une hiérarchie formée de gauche à droite.Route value invalidation works on the assumption that the app's URL scheme is hierarchical, with a hierarchy formed from left-to-right. Examinez le modèle de routage de contrôleur de base {controller}/{action}/{id?} pour avoir une idée intuitive de son fonctionnement dans la pratique.Consider the basic controller route template {controller}/{action}/{id?} to get an intuitive sense of how this works in practice. Une modification apportée à une valeur invalide toutes les valeurs d’itinéraire qui s’affichent à droite.A change to a value invalidates all of the route values that appear to the right. Cela reflète l’hypothèse sur la hiérarchie.This reflects the assumption about hierarchy. Si l’application a une valeur ambiante pour id , et que l’opération spécifie une autre valeur pour le controller :If the app has an ambient value for id, and the operation specifies a different value for the controller:

  • id ne sera pas réutilisé car {controller} est à gauche de {id?} .id won't be reused because {controller} is to the left of {id?}.

Voici quelques exemples qui illustrent ce principe :Some examples demonstrating this principle:

  • Si les valeurs explicites contiennent une valeur pour id , la valeur ambiante de id est ignorée.If the explicit values contain a value for id, the ambient value for id is ignored. Les valeurs ambiantes pour controller et action peuvent être utilisées.The ambient values for controller and action can be used.
  • Si les valeurs explicites contiennent une valeur pour action , toute valeur ambiante pour action est ignorée.If the explicit values contain a value for action, any ambient value for action is ignored. Les valeurs ambiantes pour controller peuvent être utilisées.The ambient values for controller can be used. Si la valeur explicite de action est différente de la valeur ambiante pour action , la id valeur n’est pas utilisée.If the explicit value for action is different from the ambient value for action, the id value won't be used. Si la valeur explicite de action est identique à la valeur ambiante pour action , la id valeur peut être utilisée.If the explicit value for action is the same as the ambient value for action, the id value can be used.
  • Si les valeurs explicites contiennent une valeur pour controller , toute valeur ambiante pour controller est ignorée.If the explicit values contain a value for controller, any ambient value for controller is ignored. Si la valeur explicite de controller est différente de la valeur ambiante pour controller , les action id valeurs et ne sont pas utilisées.If the explicit value for controller is different from the ambient value for controller, the action and id values won't be used. Si la valeur explicite de controller est identique à la valeur ambiante pour controller , les action valeurs et id peuvent être utilisées.If the explicit value for controller is the same as the ambient value for controller, the action and id values can be used.

Ce processus est encore plus compliqué par l’existence d’itinéraires d’attribut et d’itinéraires conventionnels dédiés.This process is further complicated by the existence of attribute routes and dedicated conventional routes. Les itinéraires conventionnels du contrôleur, comme {controller}/{action}/{id?} spécifier une hiérarchie à l’aide de paramètres de routage.Controller conventional routes such as {controller}/{action}/{id?} specify a hierarchy using route parameters. Pour les itinéraires conventionnels dédiés et les itinéraires d’attributs vers les contrôleurs et les Razor pages :For dedicated conventional routes and attribute routes to controllers and Razor Pages:

  • Il existe une hiérarchie de valeurs de route.There is a hierarchy of route values.
  • Ils n’apparaissent pas dans le modèle.They don't appear in the template.

Dans ce cas, la génération d’URL définit le concept de valeurs requis .For these cases, URL generation defines the required values concept. Les points de terminaison créés par les contrôleurs et les Razor pages ont des valeurs requises spécifiées qui autorisent le fonctionnement de l’invalidation de la valeur de routage.Endpoints created by controllers and Razor Pages have required values specified that allow route value invalidation to work.

L’algorithme d’invalidation de la valeur de routage est en détail :The route value invalidation algorithm in detail:

  • Les noms de valeur requis sont combinés avec les paramètres de route, puis traités de gauche à droite.The required value names are combined with the route parameters, then processed from left-to-right.
  • Pour chaque paramètre, la valeur ambiante et la valeur explicite sont comparées :For each parameter, the ambient value and explicit value are compared:
    • Si la valeur ambiante et la valeur explicite sont identiques, le processus se poursuit.If the ambient value and explicit value are the same, the process continues.
    • Si la valeur ambiante est présente et que la valeur explicite n’est pas, la valeur ambiante est utilisée lors de la génération de l’URL.If the ambient value is present and the explicit value isn't, the ambient value is used when generating the URL.
    • Si la valeur ambiante n’est pas présente et si la valeur explicite est, rejetez la valeur ambiante et toutes les valeurs ambiantes suivantes.If the ambient value isn't present and the explicit value is, reject the ambient value and all subsequent ambient values.
    • Si la valeur ambiante et la valeur explicite sont présentes, et si les deux valeurs sont différentes, rejetez la valeur ambiante et toutes les valeurs ambiantes suivantes.If the ambient value and the explicit value are present, and the two values are different, reject the ambient value and all subsequent ambient values.

À ce stade, l’opération de génération d’URL est prête à évaluer les contraintes de routage.At this point, the URL generation operation is ready to evaluate route constraints. L’ensemble de valeurs acceptées est associé aux valeurs par défaut du paramètre, qui sont fournies aux contraintes.The set of accepted values is combined with the parameter default values, which is provided to constraints. Si les contraintes réussissent, l’opération continue.If the constraints all pass, the operation continues.

Ensuite, les valeurs acceptées peuvent être utilisées pour développer le modèle de routage.Next, the accepted values can be used to expand the route template. Le modèle de routage est traité :The route template is processed:

  • De gauche à droite.From left-to-right.
  • La valeur acceptée est remplacée pour chaque paramètre.Each parameter has its accepted value substituted.
  • Dans les cas spéciaux suivants :With the following special cases:
    • Si une valeur est manquante pour les valeurs acceptées et que le paramètre a une valeur par défaut, la valeur par défaut est utilisée.If the accepted values is missing a value and the parameter has a default value, the default value is used.
    • Si une valeur est manquante pour les valeurs acceptées et que le paramètre est facultatif, le traitement continue.If the accepted values is missing a value and the parameter is optional, processing continues.
    • Si un paramètre d’itinéraire à droite d’un paramètre facultatif manquant a une valeur, l’opération échoue.If any route parameter to the right of a missing optional parameter has a value, the operation fails.
    • Les paramètres par défaut et les paramètres facultatifs contigus sont réduits dans la mesure du possible.Contiguous default-valued parameters and optional parameters are collapsed where possible.

Les valeurs fournies explicitement qui ne correspondent pas à un segment de l’itinéraire sont ajoutées à la chaîne de requête.Values explicitly provided that don't match a segment of the route are added to the query string. Le tableau suivant présente le résultat en cas d’utilisation du modèle de routage {controller}/{action}/{id?}.The following table shows the result when using the route template {controller}/{action}/{id?}.

Valeurs ambiantesAmbient Values Valeurs explicitesExplicit Values RésultatResult
controller = "Home"controller = "Home" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" controller = "Order", action = "About"controller = "Order", action = "About" /Order/About
controller = "Home", color = "Red"controller = "Home", color = "Red" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" action = "About", color = "Red"action = "About", color = "Red" /Home/About?color=Red

Problèmes liés à l’invalidation de la valeur de routageProblems with route value invalidation

À partir de ASP.NET Core 3,0, certains modèles de génération d’URL utilisés dans les versions ASP.NET Core antérieures ne fonctionnent pas correctement avec la génération d’URL.As of ASP.NET Core 3.0, some URL generation schemes used in earlier ASP.NET Core versions don't work well with URL generation. L’équipe ASP.NET Core prévoit d’ajouter des fonctionnalités pour répondre à ces besoins dans une version ultérieure.The ASP.NET Core team plans to add features to address these needs in a future release. Pour le moment, la meilleure solution consiste à utiliser le routage hérité.For now the best solution is to use legacy routing.

Le code suivant montre un exemple de schéma de génération d’URL qui n’est pas pris en charge par le routage.The following code shows an example of a URL generation scheme that's not supported by routing.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("default", 
                                     "{culture}/{controller=Home}/{action=Index}/{id?}");
    endpoints.MapControllerRoute("blog", "{culture}/{**slug}", 
                                      new { controller = "Blog", action = "ReadPost", });
});

Dans le code précédent, le culture paramètre route est utilisé pour la localisation.In the preceding code, the culture route parameter is used for localization. Le souhait est de faire en sorte que le culture paramètre soit toujours accepté comme valeur ambiante.The desire is to have the culture parameter always accepted as an ambient value. Toutefois, le culture paramètre n’est pas accepté comme valeur ambiante en raison de la façon dont les valeurs requises fonctionnent :However, the culture parameter is not accepted as an ambient value because of the way required values work:

  • Dans le "default" modèle de routage, le culture paramètre route est à gauche de controller , donc les modifications apportées à controller ne sont pas invalidées culture .In the "default" route template, the culture route parameter is to the left of controller, so changes to controller won't invalidate culture.
  • Dans le "blog" modèle de routage, le culture paramètre d’itinéraire est considéré comme à droite de controller , qui apparaît dans les valeurs requises.In the "blog" route template, the culture route parameter is considered to be to the right of controller, which appears in the required values.

Configuration des métadonnées de point de terminaisonConfiguring endpoint metadata

Les liens suivants fournissent des informations sur la configuration des métadonnées de point de terminaison :The following links provide information on configuring endpoint metadata:

Correspondance d’hôte dans les itinéraires avec RequireHostHost matching in routes with RequireHost

RequireHost applique une contrainte à l’itinéraire qui requiert l’hôte spécifié.RequireHost applies a constraint to the route which requires the specified host. Le RequireHost paramètre ou [Host] peut être :The RequireHost or [Host] parameter can be:

  • Host : www.domain.com , correspond www.domain.com à n’importe quel port.Host: www.domain.com, matches www.domain.com with any port.
  • Hôte avec caractère générique : *.domain.com , correspond à, www.domain.com subdomain.domain.com ou www.subdomain.domain.com sur n’importe quel port.Host with wildcard: *.domain.com, matches www.domain.com, subdomain.domain.com, or www.subdomain.domain.com on any port.
  • Port : *:5000 , correspond au port 5000 avec n’importe quel hôte.Port: *:5000, matches port 5000 with any host.
  • Hôte et port : www.domain.com:5000 ou *.domain.com:5000 , correspond à l’hôte et au port.Host and port: www.domain.com:5000 or *.domain.com:5000, matches host and port.

Plusieurs paramètres peuvent être spécifiés à l’aide RequireHost de ou de [Host] .Multiple parameters can be specified using RequireHost or [Host]. La contrainte correspond aux hôtes valides pour l’un des paramètres.The constraint matches hosts valid for any of the parameters. Par exemple, [Host("domain.com", "*.domain.com")] correspond à domain.com , www.domain.com et subdomain.domain.com .For example, [Host("domain.com", "*.domain.com")] matches domain.com, www.domain.com, and subdomain.domain.com.

Le code suivant utilise RequireHost pour exiger l’hôte spécifié sur l’itinéraire :The following code uses RequireHost to require the specified host on the route:

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", context => context.Response.WriteAsync("Hi Contoso!"))
            .RequireHost("contoso.com");
        endpoints.MapGet("/", context => context.Response.WriteAsync("AdventureWorks!"))
            .RequireHost("adventure-works.com");
        endpoints.MapHealthChecks("/healthz").RequireHost("*:8080");
    });
}

Le code suivant utilise l' [Host] attribut sur le contrôleur pour exiger l’un des ordinateurs hôtes spécifiés :The following code uses the [Host] attribute on the controller to require any of the specified hosts:

[Host("contoso.com", "adventure-works.com")]
public class ProductController : Controller
{
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Host("example.com:8080")]
    public IActionResult Privacy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Lorsque l' [Host] attribut est appliqué à la fois au contrôleur et à la méthode d’action :When the [Host] attribute is applied to both the controller and action method:

  • L’attribut de l’action est utilisé.The attribute on the action is used.
  • L’attribut Controller est ignoré.The controller attribute is ignored.

Aide sur les performances pour le routagePerformance guidance for routing

La plupart des routages ont été mis à jour dans ASP.NET Core 3,0 pour améliorer les performances.Most of routing was updated in ASP.NET Core 3.0 to increase performance.

Quand une application présente des problèmes de performances, le routage est souvent soupçonné de le résoudre.When an app has performance problems, routing is often suspected as the problem. La raison pour laquelle le routage est suspecté est que les infrastructures comme les contrôleurs et Razor les pages indiquent le temps passé dans l’infrastructure dans leurs messages de journalisation.The reason routing is suspected is that frameworks like controllers and Razor Pages report the amount of time spent inside the framework in their logging messages. Lorsqu’il y a une différence importante entre l’heure indiquée par les contrôleurs et la durée totale de la demande :When there's a significant difference between the time reported by controllers and the total time of the request:

  • Les développeurs éliminent leur code d’application comme source du problème.Developers eliminate their app code as the source of the problem.
  • Il est courant de supposer que le routage est la cause.It's common to assume routing is the cause.

Le routage est testé sur les performances à l’aide de milliers de points de terminaison.Routing is performance tested using thousands of endpoints. Il est peu probable qu’une application typique rencontre un problème de performances tout simplement trop important.It's unlikely that a typical app will encounter a performance problem just by being too large. La cause la plus courante de la lenteur des performances de routage est généralement un intergiciel (middleware) personnalisé.The most common root cause of slow routing performance is usually a badly-behaving custom middleware.

L’exemple de code suivant illustre une technique de base pour réduire la source de délai :This following code sample demonstrates a basic technique for narrowing down the source of delay:

public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 1: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseRouting();

    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 2: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseAuthorization();

    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 3: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Timing test.");
        });
    });
}

Pour le routage temporel :To time routing:

  • Entrelacer chaque intergiciel à l’aide d’une copie de l’intergiciel (middleware) de minuterie indiquée dans le code précédent.Interleave each middleware with a copy of the timing middleware shown in the preceding code.
  • Ajoutez un identificateur unique pour corréler les données de temporisation avec le code.Add a unique identifier to correlate the timing data with the code.

Il s’agit d’une méthode de base pour réduire le délai lorsqu’il est significatif, par exemple, plus que 10ms .This is a basic way to narrow down the delay when it's significant, for example, more than 10ms. La soustraction Time 2 de Time 1 signale le temps passé dans l' UseRouting intergiciel (middleware).Subtracting Time 2 from Time 1 reports the time spent inside the UseRouting middleware.

Le code suivant utilise une approche plus compacte pour le code de minutage précédent :The following code uses a more compact approach to the preceding timing code:

public sealed class MyStopwatch : IDisposable
{
    ILogger<Startup> _logger;
    string _message;
    Stopwatch _sw;

    public MyStopwatch(ILogger<Startup> logger, string message)
    {
        _logger = logger;
        _message = message;
        _sw = Stopwatch.StartNew();
    }

    private bool disposed = false;


    public void Dispose()
    {
        if (!disposed)
        {
            _logger.LogInformation("{Message }: {ElapsedMilliseconds}ms",
                                    _message, _sw.ElapsedMilliseconds);

            disposed = true;
        }
    }
}
public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
    int count = 0;
    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }

    });

    app.UseRouting();

    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }
    });

    app.UseAuthorization();

    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Timing test.");
        });
    });
}

Fonctionnalités de routage potentiellement onéreusesPotentially expensive routing features

La liste suivante fournit des informations sur les fonctionnalités de routage relativement coûteuses par rapport aux modèles de routage de base :The following list provides some insight into routing features that are relatively expensive compared with basic route templates:

  • Expressions régulières : il est possible d’écrire des expressions régulières complexes ou ayant une durée d’exécution longue avec une petite quantité d’entrée.Regular expressions: It's possible to write regular expressions that are complex, or have long running time with a small amount of input.

  • Segments complexes ( {x}-{y}-{z} ) :Complex segments ({x}-{y}-{z}):

    • Sont beaucoup plus coûteuses que l’analyse d’un segment de chemin d’accès d’URL normal.Are significantly more expensive than parsing a regular URL path segment.
    • Entraîne l’allocation de beaucoup plus de sous-chaînes.Result in many more substrings being allocated.
    • La logique de segment complexe n’a pas été mise à jour dans ASP.NET Core mise à jour des performances de routage 3,0.The complex segment logic was not updated in ASP.NET Core 3.0 routing performance update.
  • Accès synchrone aux données : de nombreuses applications complexes ont accès aux bases de données dans le cadre de leur routage.Synchronous data access: Many complex apps have database access as part of their routing. ASP.NET Core 2,2 et le routage antérieur peuvent ne pas fournir les points d’extensibilité appropriés pour prendre en charge le routage de l’accès aux bases de données.ASP.NET Core 2.2 and earlier routing might not provide the right extensibility points to support database access routing. Par exemple, IRouteConstraint , et IActionConstraint sont synchrones.For example, IRouteConstraint, and IActionConstraint are synchronous. Les points d’extensibilité tels que MatcherPolicy et EndpointSelectorContext sont asynchrones.Extensibility points such as MatcherPolicy and EndpointSelectorContext are asynchronous.

Conseils pour les auteurs de bibliothèqueGuidance for library authors

Cette section contient des conseils pour les auteurs de bibliothèque qui créent sur le routage.This section contains guidance for library authors building on top of routing. Ces détails visent à garantir que les développeurs d’applications ont une bonne expérience en utilisant des bibliothèques et des infrastructures qui étendent le routage.These details are intended to ensure that app developers have a good experience using libraries and frameworks that extend routing.

Définir des points de terminaisonDefine endpoints

Pour créer une infrastructure qui utilise le routage pour la correspondance d’URL, commencez par définir une expérience utilisateur qui s’appuie sur UseEndpoints .To create a framework that uses routing for URL matching, start by defining a user experience that builds on top of UseEndpoints.

Effectuez une génération par-dessus IEndpointRouteBuilder .DO build on top of IEndpointRouteBuilder. Cela permet aux utilisateurs de composer votre infrastructure avec d’autres fonctionnalités de ASP.NET Core sans confusion.This allows users to compose your framework with other ASP.NET Core features without confusion. Chaque modèle de ASP.NET Core comprend le routage.Every ASP.NET Core template includes routing. Supposons que le routage est présent et familier pour les utilisateurs.Assume routing is present and familiar for users.

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...);

    endpoints.MapHealthChecks("/healthz");
});

Retournez un type concret sealed à partir d’un appel à MapMyFramework(...) qui implémente IEndpointConventionBuilder .DO return a sealed concrete type from a call to MapMyFramework(...) that implements IEndpointConventionBuilder. La plupart des méthodes d’infrastructure Map... suivent ce modèle.Most framework Map... methods follow this pattern. L' IEndpointConventionBuilder interface :The IEndpointConventionBuilder interface:

  • Permet la composition des métadonnées.Allows composability of metadata.
  • Est ciblé par une variété de méthodes d’extension.Is targeted by a variety of extension methods.

La déclaration de votre propre type vous permet d’ajouter vos propres fonctionnalités propres au Framework au générateur.Declaring your own type allows you to add your own framework-specific functionality to the builder. Il est OK d’inclure dans un wrapper un générateur déclaré par l’infrastructure et de transférer des appels vers celui-ci.It's ok to wrap a framework-declared builder and forward calls to it.

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...).RequireAuthorization()
                                 .WithMyFrameworkFeature(awesome: true);

    endpoints.MapHealthChecks("/healthz");
});

Envisagez d’écrire votre propre EndpointDataSource .CONSIDER writing your own EndpointDataSource. EndpointDataSource est la primitive de bas niveau pour déclarer et mettre à jour une collection de points de terminaison.EndpointDataSource is the low-level primitive for declaring and updating a collection of endpoints. EndpointDataSource est une API puissante utilisée par les contrôleurs et les Razor pages.EndpointDataSource is a powerful API used by controllers and Razor Pages.

Les tests de routage ont un exemple de base d’une source de données qui ne met pas à jour.The routing tests have a basic example of a non-updating data source.

N’essayez pas d’inscrire un EndpointDataSource par défaut.DO NOT attempt to register an EndpointDataSource by default. Obligez les utilisateurs à inscrire votre infrastructure dans UseEndpoints .Require users to register your framework in UseEndpoints. La philosophie du routage est que rien n’est inclus par défaut et qu’il UseEndpoints s’agit de l’emplacement où inscrire des points de terminaison.The philosophy of routing is that nothing is included by default, and that UseEndpoints is the place to register endpoints.

Création d’un intergiciel (middleware) intégré au routageCreating routing-integrated middleware

Envisagez de définir des types de métadonnées en tant qu’interface.CONSIDER defining metadata types as an interface.

Vous pouvez utiliser les types de métadonnées en tant qu’attribut sur les classes et les méthodes.DO make it possible to use metadata types as an attribute on classes and methods.

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

Les infrastructures comme les contrôleurs et les Razor pages prennent en charge l’application des attributs de métadonnées aux types et aux méthodes.Frameworks like controllers and Razor Pages support applying metadata attributes to types and methods. Si vous déclarez des types de métadonnées :If you declare metadata types:

  • Rendez-les accessibles en tant qu' attributs.Make them accessible as attributes.
  • La plupart des utilisateurs sont habitués à appliquer des attributs.Most users are familiar with applying attributes.

La déclaration d’un type de métadonnées en tant qu’interface ajoute une autre couche de flexibilité :Declaring a metadata type as an interface adds another layer of flexibility:

  • Les interfaces sont composables.Interfaces are composable.
  • Les développeurs peuvent déclarer leurs propres types qui combinent plusieurs stratégies.Developers can declare their own types that combine multiple policies.

Vous pouvez remplacer les métadonnées, comme illustré dans l’exemple suivant :DO make it possible to override metadata, as shown in the following example:

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class SuppressCoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => false;
}

[CoolMetadata]
public class MyController : Controller
{
    public void MyCool() { }

    [SuppressCoolMetadata]
    public void Uncool() { }
}

La meilleure façon de suivre ces instructions consiste à éviter de définir des métadonnées de marqueur:The best way to follow these guidelines is to avoid defining marker metadata:

  • Ne cherchez pas simplement la présence d’un type de métadonnées.Don't just look for the presence of a metadata type.
  • Définissez une propriété sur les métadonnées et vérifiez la propriété.Define a property on the metadata and check the property.

La collection de métadonnées est triée et prend en charge le remplacement par priorité.The metadata collection is ordered and supports overriding by priority. Dans le cas de contrôleurs, les métadonnées de la méthode d’action sont plus spécifiques.In the case of controllers, metadata on the action method is most specific.

Faites en sorte que les intergiciels (middleware) soient utiles avec et sans routage.DO make middleware useful with and without routing.

app.UseRouting();

app.UseAuthorization(new AuthorizationPolicy() { ... });

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...).RequireAuthorization();
});

À titre d’exemple, considérez l' UseAuthorization intergiciel (middleware).As an example of this guideline, consider the UseAuthorization middleware. L’intergiciel d’autorisation vous permet de passer une stratégie de secours.The authorization middleware allows you to pass in a fallback policy. La stratégie de secours, si elle est spécifiée, s’applique aux deux :The fallback policy, if specified, applies to both:

  • Points de terminaison sans stratégie spécifiée.Endpoints without a specified policy.
  • Les demandes qui ne correspondent pas à un point de terminaison.Requests that don't match an endpoint.

Cela rend l’intergiciel (middleware) d’autorisation utile en dehors du contexte du routage.This makes the authorization middleware useful outside of the context of routing. L’intergiciel d’autorisation peut être utilisé pour la programmation d’intergiciel (middleware) classique.The authorization middleware can be used for traditional middleware programming.

Diagnostics de débogageDebug diagnostics

Pour une sortie de diagnostic de routage détaillée, affectez à la valeur Logging:LogLevel:Microsoft Debug .For detailed routing diagnostic output, set Logging:LogLevel:Microsoft to Debug. Dans l’environnement de développement, définissez le niveau de journalisation dans appsettings.Development.jssur:In the development environment, set the log level in appsettings.Development.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Le routage est chargé de mapper les URI de requête aux points de terminaison et de distribuer les demandes entrantes à ces points de terminaison.Routing is responsible for mapping request URIs to endpoints and dispatching incoming requests to those endpoints. Les routes sont définies dans l’application et configurées au démarrage de l’application.Routes are defined in the app and configured when the app starts. Une route peut éventuellement extraire des valeurs de l’URL contenue dans la requête, et ces valeurs peuvent ensuite être utilisées pour le traitement de la requête.A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. À l’aide des informations de routage de l’application, le routage est également en mesure de générer des URL qui mappent aux points de terminaison.Using route information from the app, routing is also able to generate URLs that map to endpoints.

Pour utiliser les scénarios de routage les plus récents dans ASP.NET Core 2.2, spécifiez la version de compatibilité à l’inscription des services MVC dans Startup.ConfigureServices :To use the latest routing scenarios in ASP.NET Core 2.2, specify the compatibility version to the MVC services registration in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

L’option EnableEndpointRouting détermine si le routage doit utiliser en interne une logique basée sur les points de terminaison ou la logique basée sur IRouter d’ASP.NET Core 2.1 ou antérieur.The EnableEndpointRouting option determines if routing should internally use endpoint-based logic or the IRouter-based logic of ASP.NET Core 2.1 or earlier. Quand la version de compatibilité est définie sur 2.2 ou ultérieur, la valeur par défaut est true.When the compatibility version is set to 2.2 or later, the default value is true. Définissez la valeur sur false pour utiliser la logique de routage antérieure :Set the value to false to use the prior routing logic:

// Use the routing logic of ASP.NET Core 2.1 or earlier:
services.AddMvc(options => options.EnableEndpointRouting = false)
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Pour plus d’informations sur le routage basé sur IRouter, consultez la version ASP.NET Core 2.1 de cette rubrique.For more information on IRouter-based routing, see the ASP.NET Core 2.1 version of this topic.

Important

Ce document traite du routage ASP.NET Core de bas niveau.This document covers low-level ASP.NET Core routing. Pour plus d’informations sur le routage ASP.NET Core MVC, consultez Routage vers les actions du contrôleur dans ASP.NET Core.For information on ASP.NET Core MVC routing, see Routage vers les actions du contrôleur dans ASP.NET Core. Pour plus d’informations sur les conventions de routage dans les Razor pages, consultez Razor Conventions de routage et d’application des pages dans ASP.NET Core .For information on routing conventions in Razor Pages, see Razor Conventions de routage et d’application des pages dans ASP.NET Core.

Afficher ou télécharger l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Concepts de base du routageRouting basics

La plupart des applications doivent choisir un schéma de routage de base et descriptif pour que les URL soient lisibles et explicites.Most apps should choose a basic and descriptive routing scheme so that URLs are readable and meaningful. La route conventionnelle par défaut {controller=Home}/{action=Index}/{id?} :The default conventional route {controller=Home}/{action=Index}/{id?}:

  • Prend en charge un schéma de routage de base et descriptif.Supports a basic and descriptive routing scheme.
  • Est un point de départ pratique pour les applications basées sur une interface utilisateur.Is a useful starting point for UI-based apps.

Les développeurs ajoutent généralement des itinéraires succincts supplémentaires aux zones à trafic élevé d’une application dans des situations particulières en utilisant le routage d’attributs ou des itinéraires conventionnels dédiés.Developers commonly add additional terse routes to high-traffic areas of an app in specialized situations using attribute routing or dedicated conventional routes. Les exemples de situations spécialisées incluent les points de terminaison de blog et de commerce électronique.Specialized situations examples include, blog and ecommerce endpoints.

Les API web doivent utiliser le routage d’attributs pour modéliser les fonctionnalités de l’application sous la forme d’un ensemble de ressources dans lequel les opérations sont représentées par des verbes HTTP.Web APIs should use attribute routing to model the app's functionality as a set of resources where operations are represented by HTTP verbs. Cela signifie que de nombreuses opérations, par exemple, obtenir et poster, sur la même ressource logique utilisent la même URL.This means that many operations, for example, GET, and POST, on the same logical resource use the same URL. Le routage d’attributs fournit le niveau de contrôle nécessaire pour concevoir avec soin la disposition des points de terminaison publics d’une API.Attribute routing provides a level of control that's needed to carefully design an API's public endpoint layout.

Razor Pages les applications utilisent le routage conventionnel par défaut pour servir des ressources nommées dans le dossier pages d’une application.Razor Pages apps use default conventional routing to serve named resources in the Pages folder of an app. Des conventions supplémentaires vous permettent de personnaliser le Razor comportement de routage des pages.Additional conventions are available that allow you to customize Razor Pages routing behavior. Pour plus d’informations, consultez Présentation Razor des pages dans ASP.net Core et Razor Conventions de routage et d’application des pages dans ASP.NET Core.For more information, see Présentation Razor des pages dans ASP.net Core and Razor Conventions de routage et d’application des pages dans ASP.NET Core.

La prise en charge de la génération d’URL permet de développer l’application sans coder en dur les URL pour lier l’application.URL generation support allows the app to be developed without hard-coding URLs to link the app together. Cette prise en charge permet de commencer avec une configuration de routage de base, puis de modifier les routes une fois que la disposition des ressources de l’application est déterminée.This support allows for starting with a basic routing configuration and modifying the routes after the app's resource layout is determined.

Le routage utilise des points de terminaison ( Endpoint ) pour représenter des points de terminaison logiques dans une application.Routing uses endpoints (Endpoint) to represent logical endpoints in an app.

Un point de terminaison définit un délégué pour traiter les requêtes et une collection de métadonnées arbitraires.An endpoint defines a delegate to process requests and a collection of arbitrary metadata. Les métadonnées sont utilisées pour implémenter des problèmes transversaux basés sur des stratégies et une configuration attachées à chaque point de terminaison.The metadata is used implement cross-cutting concerns based on policies and configuration attached to each endpoint.

Le système de routage a les caractéristiques suivantes :The routing system has the following characteristics:

  • Une syntaxe des modèles de route est utilisée pour définir des routes avec des paramètres de route tokenisés.Route template syntax is used to define routes with tokenized route parameters.

  • La configuration de points de terminaison de style conventionnel et de style « attribut » est autorisée.Conventional-style and attribute-style endpoint configuration is permitted.

  • IRouteConstraint est utilisé pour déterminer si un paramètre d’URL contient une valeur valide pour une contrainte de point de terminaison donné.IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.

  • Les modèles d’application, tels que MVC/ Razor pages, inscrivent tous leurs points de terminaison, qui ont une implémentation prévisible des scénarios de routage.App models, such as MVC/Razor Pages, register all of their endpoints, which have a predictable implementation of routing scenarios.

  • L’implémentation du routage prend des décisions de routage partout où vous le souhaitez dans le pipeline de middleware (intergiciel).The routing implementation makes routing decisions wherever desired in the middleware pipeline.

  • Le middleware qui apparaît après un middleware de routage peut inspecter le résultat de la décision du middleware de routage quant au point de terminaison d’un URI de requête donné.Middleware that appears after a Routing Middleware can inspect the result of the Routing Middleware's endpoint decision for a given request URI.

  • Il est possible d’énumérer tous les points de terminaison dans l’application n’importe où dans le pipeline de middleware.It's possible to enumerate all of the endpoints in the app anywhere in the middleware pipeline.

  • Une application peut utiliser le routage pour générer des URL (par exemple pour la redirection ou pour des liens) en fonction des informations des points de terminaison et éviter ainsi les URL codées en dur, ce qui facilite la maintenance.An app can use routing to generate URLs (for example, for redirection or links) based on endpoint information and thus avoid hard-coded URLs, which helps maintainability.

  • La génération d’URL est basée sur des adresses, qui prennent en charge l’extensibilité arbitraire :URL generation is based on addresses, which support arbitrary extensibility:

Notes

Avec la publication du routage de point de terminaison dans ASP.NET Core 2,2, la liaison de point de terminaison est limitée aux Razor actions et pages MVC/pages.With the release of endpoint routing in ASP.NET Core 2.2, endpoint linking is limited to MVC/Razor Pages actions and pages. Les expansions des fonctionnalités de liaison de point de terminaison sont prévues pour les versions futures.The expansions of endpoint-linking capabilities is planned for future releases.

Le routage est connecté au pipeline de l’intergiciel (middleware) par la classe RouterMiddleware.Routing is connected to the middleware pipeline by the RouterMiddleware class. ASP.net Core MVC ajoute le routage au pipeline de l’intergiciel (middleware) dans le cadre de sa configuration et gère le routage dans les applications MVC et Razor pages.ASP.NET Core MVC adds routing to the middleware pipeline as part of its configuration and handles routing in MVC and Razor Pages apps. Pour découvrir comment utiliser le routage en tant que composant autonome, consultez la section Utiliser le middleware de routage.To learn how to use routing as a standalone component, see the Use Routing Middleware section.

Correspondance d’URLURL matching

La correspondance d’URL est le processus par lequel le routage distribue une requête entrante à un point de terminaison.URL matching is the process by which routing dispatches an incoming request to an endpoint. Ce processus est basé sur des données présentes dans le chemin de l’URL, mais il peut être étendu pour prendre en compte toutes les données de la requête.This process is based on data in the URL path but can be extended to consider any data in the request. La possibilité de distribuer des requêtes à des gestionnaires distincts est essentielle pour adapter la taille et la complexité d’une application.The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

Le système de routage dans le routage de point de terminaison est responsable de toutes les décisions de distribution.The routing system in endpoint routing is responsible for all dispatching decisions. Comme le middleware applique des stratégies basées sur le point de terminaison sélectionné, il est important que les décisions susceptibles d’affecter la distribution ou l’application des stratégies de sécurité soient prises au sein du système de routage.Since the middleware applies policies based on the selected endpoint, it's important that any decision that can affect dispatching or the application of security policies is made inside the routing system.

Quand le délégué du point de terminaison est exécuté, les propriétés de RouteContext.RouteData sont définies sur des valeurs appropriées en fonction du traitement des requêtes effectué jusqu’à présent.When the endpoint delegate is executed, the properties of RouteContext.RouteData are set to appropriate values based on the request processing performed thus far.

RouteData.Values est un dictionnaire de valeurs de route produites à partir de la route.RouteData.Values is a dictionary of route values produced from the route. Ces valeurs sont généralement déterminées en décomposant l’URL en jetons. Elles peuvent être utilisées pour accepter l’entrée d’utilisateur ou pour prendre d’autres décisions relatives à la distribution à l’intérieur de l’application.These values are usually determined by tokenizing the URL and can be used to accept user input or to make further dispatching decisions inside the app.

RouteData.DataTokens est un conteneur de propriétés des données supplémentaires associées à la route mise en correspondance.RouteData.DataTokens is a property bag of additional data related to the matched route. Les DataTokens sont fournis pour prendre en charge l’association de données d’état à chaque route, de façon que l’application puisse prendre des décisions en fonction de la route avec laquelle la correspondance a été établie.DataTokens are provided to support associating state data with each route so that the app can make decisions based on which route matched. Ces valeurs sont définies par le développeur et n’affectent pas le comportement du routage de quelque manière que ce soit.These values are developer-defined and do not affect the behavior of routing in any way. De plus, les valeurs dissimulées dans RouteData.DataTokens peuvent être de n’importe quel type, contrairement aux valeurs RouteData.Values, qui doivent être convertibles en chaînes et à partir de chaînes.Additionally, values stashed in RouteData.DataTokens can be of any type, in contrast to RouteData.Values, which must be convertible to and from strings.

RouteData.Routers est une liste des routes qui ont participé à la mise en correspondance correcte de la requête.RouteData.Routers is a list of the routes that took part in successfully matching the request. Les routes peuvent être imbriquées les unes dans les autres.Routes can be nested inside of one another. La propriété Routers reflète le chemin à travers l’arborescence logique des routes qui ont généré une correspondance.The Routers property reflects the path through the logical tree of routes that resulted in a match. En général le premier élément de Routers est la collection de routes et il doit être utilisé pour la génération d’URL.Generally, the first item in Routers is the route collection and should be used for URL generation. Le dernier élément de Routers est le gestionnaire de routage avec lequel la correspondance a été établie.The last item in Routers is the route handler that matched.

Génération d’URL avec LinkGeneratorURL generation with LinkGenerator

La génération d’URL est le processus par lequel le routage peut créer un chemin d’URL basé sur un ensemble de valeurs de route.URL generation is the process by which routing can create a URL path based on a set of route values. Ceci permet une séparation logique entre vos points de terminaison et les URL qui y accèdent.This allows for a logical separation between your endpoints and the URLs that access them.

Le routage des points de terminaison inclut l’API de générateur de liens (LinkGenerator).Endpoint routing includes the Link Generator API (LinkGenerator). LinkGenerator est un service singleton qui peut être récupéré à partir de di.LinkGenerator is a singleton service that can be retrieved from DI. L’API peut être utilisée en dehors du contexte d’une requête en cours d’exécution.The API can be used outside of the context of an executing request. Le IUrlHelper de MVC et les scénarios qui s’appuient sur IUrlHelper, comme les Tag Helpers, les helpers HTML et les résultats d’action, utilisent le générateur de liens pour fournir les fonctionnalités de création de liens.MVC's IUrlHelper and scenarios that rely on IUrlHelper, such as Tag Helpers, HTML Helpers, and Action Results, use the link generator to provide link generating capabilities.

Le générateur de liens est basé sur le concept d’une adresse et de schémas d’adresse.The link generator is backed by the concept of an address and address schemes. Un schéma d’adresse est un moyen de déterminer les points de terminaison à prendre en compte pour la génération de liens.An address scheme is a way of determining the endpoints that should be considered for link generation. Par exemple, les scénarios nom de l’itinéraire et valeurs de routage de nombreux utilisateurs sont familiarisés avec MVC/les Razor pages sont implémentés en tant que schéma d’adresse.For example, the route name and route values scenarios many users are familiar with from MVC/Razor Pages are implemented as an address scheme.

Le générateur de liens peut lier des Razor actions et des pages MVC/pages à l’aide des méthodes d’extension suivantes :The link generator can link to MVC/Razor Pages actions and pages via the following extension methods:

Une surcharge de ces méthodes accepte des arguments qui incluent le HttpContext.An overload of these methods accepts arguments that include the HttpContext. Ces méthodes sont fonctionnellement équivalentes à Url.Action et à Url.Page, mais elles offrent davantage de flexibilité et d’options.These methods are functionally equivalent to Url.Action and Url.Page but offer additional flexibility and options.

Les méthodes GetPath* sont les plus proches de Url.Action et de Url.Page en ce qu’elles génèrent un URI contenant un chemin absolu.The GetPath* methods are most similar to Url.Action and Url.Page in that they generate a URI containing an absolute path. Les méthodes GetUri* génèrent toujours un URI absolu contenant un schéma et un hôte.The GetUri* methods always generate an absolute URI containing a scheme and host. Les méthodes qui acceptent un HttpContext génèrent un URI dans le contexte de la requête en cours d’exécution.The methods that accept an HttpContext generate a URI in the context of the executing request. Les valeurs de route ambiante, le chemin de base d’URL, le schéma et l’hôte de la requête en cours d’exécution sont utilisés, sauf s’ils sont remplacés.The ambient route values, URL base path, scheme, and host from the executing request are used unless overridden.

LinkGenerator est appelé avec une adresse.LinkGenerator is called with an address. La génération d’un URI se fait en deux étapes :Generating a URI occurs in two steps:

  1. Une adresse est liée à une liste de points de terminaison qui correspondent à l’adresse.An address is bound to a list of endpoints that match the address.
  2. Le RoutePattern de chaque point de terminaison est évalué jusqu’à ce qu’un modèle de route correspondant aux valeurs fournies soit trouvé.Each endpoint's RoutePattern is evaluated until a route pattern that matches the supplied values is found. Le résultat obtenu est combiné avec d’autres parties de l’URI fournies par le générateur de liens, puis il est retourné.The resulting output is combined with the other URI parts supplied to the link generator and returned.

Les méthodes fournies par LinkGenerator prennent en charge des fonctionnalités de génération de liens standard pour n’importe quel type d’adresse.The methods provided by LinkGenerator support standard link generation capabilities for any type of address. La façon la plus pratique d’utiliser le générateur de liens est de le faire via des méthodes d’extension qui effectuent des opérations pour un type d’adresse spécifique.The most convenient way to use the link generator is through extension methods that perform operations for a specific address type.

Méthode d’extensionExtension Method DescriptionDescription
GetPathByAddress Génère un URI avec un chemin absolu basé sur les valeurs fournies.Generates a URI with an absolute path based on the provided values.
GetUriByAddress Génère un URI absolu basé sur les valeurs fournies.Generates an absolute URI based on the provided values.

Avertissement

Faites attention aux implications suivantes de l’appel de méthodes LinkGenerator :Pay attention to the following implications of calling LinkGenerator methods:

  • Utilisez les méthodes d’extension GetUri* avec précaution dans une configuration d’application qui ne valide pas l’en-tête Host des requêtes entrantes.Use GetUri* extension methods with caution in an app configuration that doesn't validate the Host header of incoming requests. Si l’en-tête Host des requêtes entrantes n’est pas validé, l’entrée de requête non approuvée peut être renvoyée au client dans les URI d’une page/vue.If the Host header of incoming requests isn't validated, untrusted request input can be sent back to the client in URIs in a view/page. Nous recommandons que toutes les applications de production configurent leur serveur pour qu’il valide l’en-tête Host par rapport à des valeurs valides connues.We recommend that all production apps configure their server to validate the Host header against known valid values.

  • Utilisez LinkGenerator avec précaution dans le middleware en combinaison avec Map ou MapWhen.Use LinkGenerator with caution in middleware in combination with Map or MapWhen. Map* modifie le chemin de base de la requête en cours d’exécution, ce qui affecte la sortie de la génération de liens.Map* changes the base path of the executing request, which affects the output of link generation. Toutes les API LinkGenerator permettent la spécification d’un chemin de base.All of the LinkGenerator APIs allow specifying a base path. Spécifiez toujours un chemin de base vide pour annuler l’effet de Map* sur la génération de liens.Always specify an empty base path to undo Map*'s affect on link generation.

Différences par rapport aux versions précédentes du routageDifferences from earlier versions of routing

Il existe quelques différences entre le routage de points de terminaison d’ASP.NET Core 2.2 ou ultérieur et celui des versions antérieures d’ASP.NET Core :A few differences exist between endpoint routing in ASP.NET Core 2.2 or later and earlier versions of routing in ASP.NET Core:

  • Le système de routage de points de terminaison ne prend pas en charge l’extensibilité basée sur IRouter, notamment l’héritage de Route.The endpoint routing system doesn't support IRouter-based extensibility, including inheriting from Route.

  • Le routage de points de terminaison ne prend pas en charge WebApiCompatShim.Endpoint routing doesn't support WebApiCompatShim. Utilisez la version de compatibilité 2,1 ( .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) ) pour continuer à utiliser le shim de compatibilité.Use the 2.1 compatibility version (.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)) to continue using the compatibility shim.

  • Le routage de points de terminaison a un comportement différent pour la casse des URI générés lors de l’utilisation de routes conventionnelles.Endpoint Routing has different behavior for the casing of generated URIs when using conventional routes.

    Considérez le modèle de route par défaut suivant :Consider the following default route template:

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

    Supposez que vous générez un lien vers une action avec la route suivante :Suppose you generate a link to an action using the following route:

    var link = Url.Action("ReadPost", "blog", new { id = 17, });
    

    Avec le routage basé sur IRouter, ce code génère un URI /blog/ReadPost/17, qui respecte la casse de la valeur de la route fournie.With IRouter-based routing, this code generates a URI of /blog/ReadPost/17, which respects the casing of the provided route value. Le routage de points de terminaison dans ASP.NET Core 2.2 ou ultérieur produit /Blog/ReadPost/17 (« Blog » commence par une majuscule).Endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 ("Blog" is capitalized). Le routage de points de terminaison fournit l’interface IOutboundParameterTransformer, qui peut être utilisée pour personnaliser ce comportement de façon globale ou pour appliquer des conventions différentes pour le mappage d’URL.Endpoint routing provides the IOutboundParameterTransformer interface that can be used to customize this behavior globally or to apply different conventions for mapping URLs.

    Pour plus d’informations, consultez la section Informations de référence sur les transformateurs de paramètre.For more information, see the Parameter transformer reference section.

  • La génération de liens utilisée par MVC/ Razor pages avec des itinéraires conventionnels se comporte différemment lors de la tentative de liaison à un contrôleur, une action ou une page qui n’existe pas.Link Generation used by MVC/Razor Pages with conventional routes behaves differently when attempting to link to an controller/action or page that doesn't exist.

    Considérez le modèle de route par défaut suivant :Consider the following default route template:

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

    Supposez que vous générez un lien vers une action en utilisant le modèle par défaut avec ce qui suit :Suppose you generate a link to an action using the default template with the following:

    var link = Url.Action("ReadPost", "Blog", new { id = 17, });
    

    Avec le routage basé sur IRouter, le résultat est toujours /Blog/ReadPost/17, même si le BlogController n’existe pas ou n’a pas de méthode d’action ReadPost.With IRouter-based routing, the result is always /Blog/ReadPost/17, even if the BlogController doesn't exist or doesn't have a ReadPost action method. Comme prévu, le routage de points de terminaison dans ASP.NET Core 2.2 ou ultérieur produit /Blog/ReadPost/17 si la méthode d’action existe.As expected, endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 if the action method exists. Cependant, le routage de points de terminaison produit une chaîne vide si l’action n’existe pas.However, endpoint routing produces an empty string if the action doesn't exist. Sur le plan conceptuel, le routage de points de terminaison ne fait pas l’hypothèse que le point de terminaison existe si l’action n’existe pas.Conceptually, endpoint routing doesn't assume that the endpoint exists if the action doesn't exist.

  • L’algorithme d’invalidation de valeur ambiante de la génération de liens se comporte différemment quand il est utilisé avec le routage de points de terminaison.The link generation ambient value invalidation algorithm behaves differently when used with endpoint routing.

    L’invalidation de valeur ambiante est l’algorithme qui décide quelles valeurs de route provenant de la requête en cours d’exécution (les valeurs ambiantes) peuvent être utilisées dans les opérations de génération de liens.Ambient value invalidation is the algorithm that decides which route values from the currently executing request (the ambient values) can be used in link generation operations. Le routage conventionnel a toujours invalidé les valeurs de route supplémentaires lors de la liaison à une action différente.Conventional routing always invalidated extra route values when linking to a different action. Le routage d’attributs n’a pas ce comportement avant la publication d’ASP.NET Core 2.2.Attribute routing didn't have this behavior prior to the release of ASP.NET Core 2.2. Dans les versions antérieures d’ASP.NET Core, les liens vers une autre action utilisant les mêmes noms de paramètre de route provoquaient des erreurs de génération de liens.In earlier versions of ASP.NET Core, links to another action that use the same route parameter names resulted in link generation errors. Dans ASP.NET Core 2.2 ou ultérieur, les deux formes de routage invalident les valeurs lors de la liaison vers une autre action.In ASP.NET Core 2.2 or later, both forms of routing invalidate values when linking to another action.

    Considérez l’exemple suivant dans ASP.NET Core 2.1 ou antérieur.Consider the following example in ASP.NET Core 2.1 or earlier. Lors de la liaison à une autre action (ou une autre page), les valeurs de route peuvent être réutilisées de façon non souhaitée.When linking to another action (or another page), route values can be reused in undesirable ways.

    Dans /Pages/Store/Product.cshtml :In /Pages/Store/Product.cshtml:

    @page "{id}"
    @Url.Page("/Login")
    

    Dans /Pages/Login.cshtml :In /Pages/Login.cshtml:

    @page "{id?}"
    

    Si l’URI est /Store/Product/18 dans ASP.NET Core 2.1 ou antérieur, le lien généré sur la page Store/Info par @Url.Page("/Login") est /Login/18.If the URI is /Store/Product/18 in ASP.NET Core 2.1 or earlier, the link generated on the Store/Info page by @Url.Page("/Login") is /Login/18. La valeur 18 pour id est réutilisée, même si la destination du lien est une partie entièrement différente de l’application.The id value of 18 is reused, even though the link destination is different part of the app entirely. La valeur de route pour id dans le contexte de la page /Login est probablement une valeur d’ID utilisateur, et non pas une valeur d’ID de produit de magasin.The id route value in the context of the /Login page is probably a user ID value, not a store product ID value.

    Dans le routage de points de terminaison avec ASP.NET Core 2.2 ou ultérieur, le résultat est /Login.In endpoint routing with ASP.NET Core 2.2 or later, the result is /Login. Les valeurs ambiantes ne sont pas réutilisées quand la destination liée est une action ou une page différente.Ambient values aren't reused when the linked destination is a different action or page.

  • Syntaxe des paramètres de route avec aller-retour : les barres obliques ne sont pas encodées lors de l’utilisation d’une syntaxe de paramètre passe-partout avec double astérisque (**).Round-tripping route parameter syntax: Forward slashes aren't encoded when using a double-asterisk (**) catch-all parameter syntax.

    Pendant la génération de liens, le système de routage encode la valeur capturée dans un paramètre passe-partout avec double astérisque (**) (par exemple {**myparametername}) sans les barres obliques.During link generation, the routing system encodes the value captured in a double-asterisk (**) catch-all parameter (for example, {**myparametername}) except the forward slashes. Le passe-partout avec double astérisque est pris en charge avec le routage basé sur IRouter dans ASP.NET Core 2.2 ou ultérieur.The double-asterisk catch-all is supported with IRouter-based routing in ASP.NET Core 2.2 or later.

    La syntaxe de paramètre passe-partout avec un seul astérisque dans les versions antérieures d’ASP.NET Core ({*myparametername}) reste prise en charge, et les barres obliques sont encodées.The single asterisk catch-all parameter syntax in prior versions of ASP.NET Core ({*myparametername}) remains supported, and forward slashes are encoded.

    RouteRoute Lien généré avecLink generated with
    Url.Action(new { category = "admin/products" })
    /search/{*page} /search/admin%2Fproducts (la barre oblique est encodée)/search/admin%2Fproducts (the forward slash is encoded)
    /search/{**page} /search/admin/products

Exemple de middlewareMiddleware example

Dans l’exemple suivant, un middleware utilise l’API LinkGenerator pour créer un lien vers une méthode d’action qui liste les produits d’un magasin.In the following example, a middleware uses the LinkGenerator API to create link to an action method that lists store products. L’utilisation du générateur de liens en l’injectant dans une classe et en appelant GenerateLink est disponible pour n’importe quelle classe dans une application.Using the link generator by injecting it into a class and calling GenerateLink is available to any class in an app.

using Microsoft.AspNetCore.Routing;

public class ProductsLinkMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsLinkMiddleware(RequestDelegate next, LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var url = _linkGenerator.GetPathByAction("ListProducts", "Store");

        httpContext.Response.ContentType = "text/plain";

        await httpContext.Response.WriteAsync($"Go to {url} to see our products.");
    }
}

Créer des itinérairesCreate routes

La plupart des applications créent des routes en appelant MapRoute ou l’une des méthodes d’extension similaires définies sur IRouteBuilder.Most apps create routes by calling MapRoute or one of the similar extension methods defined on IRouteBuilder. Toutes les méthodes d’extension de IRouteBuilder créent une instance de Route et l’ajoutent à la collection de routes.Any of the IRouteBuilder extension methods create an instance of Route and add it to the route collection.

MapRoute n’accepte pas de paramètre de gestionnaire de routage.MapRoute doesn't accept a route handler parameter. MapRoute ajoute uniquement des routes gérées par DefaultHandler.MapRoute only adds routes that are handled by the DefaultHandler. Pour plus d’informations sur le routage dans MVC, consultez Routage vers les actions du contrôleur dans ASP.NET Core.To learn more about routing in MVC, see Routage vers les actions du contrôleur dans ASP.NET Core.

L’exemple de code suivant est un exemple d’appel à MapRoute utilisé par une définition de route ASP.NET Core MVC classique :The following code example is an example of a MapRoute call used by a typical ASP.NET Core MVC route definition:

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

Ce modèle établit une correspondance avec un chemin d’URL et extrait les valeurs de route .This template matches a URL path and extracts the route values. Par exemple, le chemin /Products/Details/17 génère les valeurs de route suivantes : { controller = Products, action = Details, id = 17 }.For example, the path /Products/Details/17 generates the following route values: { controller = Products, action = Details, id = 17 }.

Les valeurs de route sont déterminées en divisant le chemin d’URL en segments et en mettant en correspondance chaque segment avec le nom des paramètres de routage dans le modèle de routage.Route values are determined by splitting the URL path into segments and matching each segment with the route parameter name in the route template. Les paramètres de routage sont nommés.Route parameters are named. Vous définissez des paramètres en plaçant leur nom entre des accolades { ... }.The parameters defined by enclosing the parameter name in braces { ... }.

Le modèle précédent peut également mettre en correspondance le chemin d’URL / et produire les valeurs { controller = Home, action = Index }.The preceding template could also match the URL path / and produce the values { controller = Home, action = Index }. Cela s’explique par le fait que les paramètres de routage {controller} et {action} ont des valeurs par défaut et que le paramètre de routage id est facultatif.This occurs because the {controller} and {action} route parameters have default values and the id route parameter is optional. Un signe égal (=) suivi d’une valeur après le nom du paramètre de routage définit une valeur par défaut pour le paramètre.An equals sign (=) followed by a value after the route parameter name defines a default value for the parameter. Un point d’interrogation (?) après le nom du paramètre de routage définit un paramètre facultatif.A question mark (?) after the route parameter name defines an optional parameter.

Les paramètres de routage ayant une valeur par défaut produisent toujours une valeur de routage quand la route correspond.Route parameters with a default value always produce a route value when the route matches. Les paramètres facultatifs ne produisent pas de valeur de route s’il n’y a pas de segment de chemin d’URL correspondant.Optional parameters don't produce a route value if there is no corresponding URL path segment. Pour obtenir une description complète des scénarios et de la syntaxe des modèles de routage, consultez la section Informations de référence sur les modèles de routage.See the Route template reference section for a thorough description of route template scenarios and syntax.

Dans l’exemple suivant, la définition du paramètre de route {id:int} définit une contrainte de route pour le paramètre de route id :In the following example, the route parameter definition {id:int} defines a route constraint for the id route parameter:

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

Ce modèle établit une correspondance avec un chemin d’URL comme /Products/Details/17, mais pas /Products/Details/Apples.This template matches a URL path like /Products/Details/17 but not /Products/Details/Apples. Les contraintes de routage implémentent IRouteConstraint et inspectent les valeurs de route pour les vérifier.Route constraints implement IRouteConstraint and inspect route values to verify them. Dans cet exemple, la valeur de route id doit être convertible en entier.In this example, the route value id must be convertible to an integer. Pour obtenir une explication des contraintes de route fournies par le framework, consultez Informations de référence sur les contraintes de route.See route-constraint-reference for an explanation of route constraints provided by the framework.

Des surcharges supplémentaires de MapRoute acceptent des values pour constraints, dataTokens et defaults.Additional overloads of MapRoute accept values for constraints, dataTokens, and defaults. L’utilisation classique de ces paramètres consiste à passer un objet typé anonymement, où les noms des propriétés du type anonyme correspondent aux noms de paramètre de routage.The typical usage of these parameters is to pass an anonymously typed object, where the property names of the anonymous type match route parameter names.

Les exemples de MapRoute suivants créent des routes équivalentes :The following MapRoute examples create equivalent routes:

routes.MapRoute(
    name: "default_route",
    template: "{controller}/{action}/{id?}",
    defaults: new { controller = "Home", action = "Index" });

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

Conseil

La syntaxe inline pour la définition des contraintes et des valeurs par défaut peut être pratique pour les routes simples.The inline syntax for defining constraints and defaults can be convenient for simple routes. Cependant, certains scénarios, comme les jetons de données, ne sont pas pris en charge par la syntaxe inline.However, there are scenarios, such as data tokens, that aren't supported by inline syntax.

L’exemple suivant montre quelques autres scénarios :The following example demonstrates a few additional scenarios:

routes.MapRoute(
    name: "blog",
    template: "Blog/{**article}",
    defaults: new { controller = "Blog", action = "ReadArticle" });

Le modèle précédent établit une correspondance avec un chemin d’URL comme /Blog/All-About-Routing/Introduction et extrait les valeurs { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }.The preceding template matches a URL path like /Blog/All-About-Routing/Introduction and extracts the values { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }. Les valeurs de route par défaut pour controller et action sont produites par la route, même s’il n’existe aucun paramètre de routage correspondant dans le modèle.The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. Il est possible de spécifier des valeurs par défaut dans le modèle de route.Default values can be specified in the route template. Le paramètre de route article est défini comme *passe-partout * par la présence d’un double astérisque (**) avant le nom du paramètre de route.The article route parameter is defined as a catch-all by the appearance of an double asterisk (**) before the route parameter name. Les paramètres de routage fourre-tout capturent le reste du chemin d’URL et peuvent également établir une correspondance avec la chaîne vide.Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

L’exemple suivant ajoute des contraintes de route et des jetons de données :The following example adds route constraints and data tokens:

routes.MapRoute(
    name: "us_english_products",
    template: "en-US/Products/{id}",
    defaults: new { controller = "Products", action = "Details" },
    constraints: new { id = new IntRouteConstraint() },
    dataTokens: new { locale = "en-US" });

Le modèle précédent établit une correspondance avec un chemin d’URL comme /en-US/Products/5, et extrait les valeurs { controller = Products, action = Details, id = 5 } et les jetons de données { locale = en-US }.The preceding template matches a URL path like /en-US/Products/5 and extracts the values { controller = Products, action = Details, id = 5 } and the data tokens { locale = en-US }.

Jetons Windows de variables locales

Génération d’URL de classe de routeRoute class URL generation

La classe Route peut également effectuer une génération d’URL en combinant un ensemble de valeurs de route et son modèle de routage.The Route class can also perform URL generation by combining a set of route values with its route template. Il s’agit logiquement du processus inverse de la mise en correspondance du chemin d’URL.This is logically the reverse process of matching the URL path.

Conseil

Pour mieux comprendre la génération d’URL, imaginez l’URL que vous voulez générer, puis pensez à la façon dont un modèle de routage établirait une correspondance avec cette URL.To better understand URL generation, imagine what URL you want to generate and then think about how a route template would match that URL. Quelles valeurs seraient produites ?What values would be produced? Cela équivaut approximativement à la façon dont la génération d’URL fonctionne dans la classe Route.This is the rough equivalent of how URL generation works in the Route class.

L’exemple suivant utilise une route par défaut ASP.NET Core MVC générale :The following example uses a general ASP.NET Core MVC default route:

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

Avec les valeurs de route { controller = Products, action = List }, l’URL /Products/List est générée.With the route values { controller = Products, action = List }, the URL /Products/List is generated. Les valeurs de route remplacent les paramètres de routage correspondant pour former le chemin d’URL.The route values are substituted for the corresponding route parameters to form the URL path. Dans la mesure où id est un paramètre de route facultatif, l’URL est générée correctement sans valeur pour id.Since id is an optional route parameter, the URL is successfully generated without a value for id.

Avec les valeurs de route { controller = Home, action = Index }, l’URL / est générée.With the route values { controller = Home, action = Index }, the URL / is generated. Les valeurs de route fournies correspondent aux valeurs par défaut, et les segments correspondant aux valeurs par défaut peuvent être omis sans risque.The provided route values match the default values, and the segments corresponding to the default values are safely omitted.

Les deux URL générées effectuent un aller-retour avec la définition de route suivante (/Home/Index et /), et produisent les mêmes valeurs de route que celles utilisées pour générer l’URL.Both URLs generated round-trip with the following route definition (/Home/Index and /) produce the same route values that were used to generate the URL.

Notes

Pour générer des URL, une application utilisant ASP.NET Core MVC doit utiliser UrlHelper au lieu d’effectuer un appel directement dans le routage.An app using ASP.NET Core MVC should use UrlHelper to generate URLs instead of calling into routing directly.

Pour plus d’informations sur la génération d’URL, consultez la section Informations de référence sur la génération d’URL.For more information on URL generation, see the Url generation reference section.

Utilisation du middleware de routageUse Routing Middleware

Référencez le métapackage Microsoft.AspNetCore.App dans le fichier projet de l’application.Reference the Microsoft.AspNetCore.App metapackage in the app's project file.

Ajoutez le routage au conteneur de service dans Startup.ConfigureServices :Add routing to the service container in Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting();
}

Les routes doivent être configurées dans la méthode Startup.Configure.Routes must be configured in the Startup.Configure method. L’exemple d’application utilise les API suivantes :The sample app uses the following APIs:

var trackPackageRouteHandler = new RouteHandler(context =>
{
    var routeValues = context.GetRouteData().Values;
    return context.Response.WriteAsync(
        $"Hello! Route values: {string.Join(", ", routeValues)}");
});

var routeBuilder = new RouteBuilder(app, trackPackageRouteHandler);

routeBuilder.MapRoute(
    "Track Package Route",
    "package/{operation:regex(^track|create$)}/{id:int}");

routeBuilder.MapGet("hello/{name}", context =>
{
    var name = context.GetRouteValue("name");
    // The route handler when HTTP GET "hello/<anything>" matches
    // To match HTTP GET "hello/<anything>/<anything>, 
    // use routeBuilder.MapGet("hello/{*name}"
    return context.Response.WriteAsync($"Hi, {name}!");
});

var routes = routeBuilder.Build();
app.UseRouter(routes);

Le tableau suivant montre les réponses avec les URI donnés.The following table shows the responses with the given URIs.

URIURI responseResponse
/package/create/3 Hello!Hello! Valeurs de route : [operation, create], [id, 3]Route values: [operation, create], [id, 3]
/package/track/-3 Hello!Hello! Valeurs de route : [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/-3/ Hello!Hello! Valeurs de route : [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/ La requête passe à travers ceci, aucune correspondance.The request falls through, no match.
GET /hello/Joe Hi, Joe!Hi, Joe!
POST /hello/Joe La requête passe à travers ceci, correspondance seulement avec HTTP GET.The request falls through, matches HTTP GET only.
GET /hello/Joe/Smith La requête passe à travers ceci, aucune correspondance.The request falls through, no match.

Le framework fournit un ensemble de méthodes d’extension pour la création de routes (RequestDelegateRouteBuilderExtensions) :The framework provides a set of extension methods for creating routes (RequestDelegateRouteBuilderExtensions):

Les méthodes Map[Verb] utilisent des contraintes pour limiter la route au verbe HTTP dans le nom de la méthode.The Map[Verb] methods use constraints to limit the route to the HTTP Verb in the method name. Par exemple, consultez MapGet et MapVerb.For example, see MapGet and MapVerb.

Informations de référence sur les modèles de routageRoute template reference

Les jetons placés entre accolades ({ ... }) définissent des paramètres de routage qui sont liés si une correspondance est trouvée pour la route.Tokens within curly braces ({ ... }) define route parameters that are bound if the route is matched. Vous pouvez définir plusieurs paramètres de routage dans un segment de route, mais ils doivent être séparés par une valeur littérale.You can define more than one route parameter in a route segment, but they must be separated by a literal value. Par exemple {controller=Home}{action=Index} n’est pas une route valide, car il n’y a aucune valeur littérale entre {controller} et {action}.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Ces paramètres de routage doivent avoir un nom, et ils autorisent la spécification d’attributs supplémentaires.These route parameters must have a name and may have additional attributes specified.

Un texte littéral autre que les paramètres de routage (par exemple, {id}) et le séparateur de chemin / doit correspondre au texte présent dans l’URL.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. La correspondance de texte ne respecte pas la casse et est basée sur la représentation décodée du chemin des URL.Text matching is case-insensitive and based on the decoded representation of the URLs path. Pour mettre en correspondance un délimiteur de paramètre de route littéral ({ ou }), placez-le dans une séquence d’échappement en répétant le caractère ({{ ou }}).To match a literal route parameter delimiter ({ or }), escape the delimiter by repeating the character ({{ or }}).

Les modèles d’URL qui tentent de capturer un nom de fichier avec une extension de fichier facultative doivent faire l’objet de considérations supplémentaires.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Prenez par exemple le modèle files/{filename}.{ext?}.For example, consider the template files/{filename}.{ext?}. Quand des valeurs existent à la fois pour filename et pour ext, les deux valeurs sont renseignées.When values for both filename and ext exist, both values are populated. Si seule une valeur existe pour filename dans l’URL, une correspondance est trouvée pour la route, car le point final (.) est facultatif.If only a value for filename exists in the URL, the route matches because the trailing period (.) is optional. Les URL suivantes correspondent à cette route :The following URLs match this route:

  • /files/myFile.txt
  • /files/myFile

Vous pouvez utiliser un astérisque (*) ou un double astérisque (**) comme préfixe d’un paramètre de route à lier au reste de l’URI.You can use an asterisk (*) or double asterisk (**) as a prefix to a route parameter to bind to the rest of the URI. Ils sont appelés des paramètres passe-partout.These are called a catch-all parameters. Par exemple, blog/{**slug} établit une correspondance avec n’importe quel URI commençant par /blog et suivi de n’importe quelle valeur, qui est affectée à la valeur de route slug.For example, blog/{**slug} matches any URI that starts with /blog and has any value following it, which is assigned to the slug route value. Les paramètres fourre-tout peuvent également établir une correspondance avec la chaîne vide.Catch-all parameters can also match the empty string.

Le paramètre fourre-tout place les caractères appropriés dans une séquence d’échappement lorsque la route est utilisée pour générer une URL, y compris les caractères de séparation de chemin (/).The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. Par exemple, la route foo/{*path} avec les valeurs de route { path = "my/path" } génère foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Notez la barre oblique d’échappement.Note the escaped forward slash. Pour les séparateurs de chemin aller-retour, utilisez le préfixe de paramètre de routage **.To round-trip path separator characters, use the ** route parameter prefix. La route foo/{**path} avec { path = "my/path" } génère foo/my/path.The route foo/{**path} with { path = "my/path" } generates foo/my/path.

Les paramètres de route peuvent avoir des valeurs par défaut, désignées en spécifiant la valeur par défaut après le nom du paramètre, séparée par un signe égal (=).Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Par exemple, {controller=Home} définit Home comme valeur par défaut de controller.For example, {controller=Home} defines Home as the default value for controller. La valeur par défaut est utilisée si aucune valeur n’est présente dans l’URL pour le paramètre.The default value is used if no value is present in the URL for the parameter. Vous pouvez rendre facultatifs les paramètres de route en ajoutant un point d’interrogation (?) à la fin du nom du paramètre, comme dans id?.Route parameters are made optional by appending a question mark (?) to the end of the parameter name, as in id?. La différence entre les valeurs facultatives et les paramètres de route par défaut est qu’un paramètre de route ayant une valeur par défaut produit toujours une valeur, tandis qu’un paramètre facultatif a une valeur seulement quand celle-ci est fournie par l’URL de requête.The difference between optional values and default route parameters is that a route parameter with a default value always produces a value—an optional parameter has a value only when a value is provided by the request URL.

Les paramètres de route peuvent avoir des contraintes, qui doivent correspondre à la valeur de route liée à partir de l’URL.Route parameters may have constraints that must match the route value bound from the URL. L’ajout d’un signe deux-points (:) et d’un nom de contrainte après le nom du paramètre de routage spécifie une contrainte inline sur un paramètre de routage.Adding a colon (:) and constraint name after the route parameter name specifies an inline constraint on a route parameter. Si la contrainte nécessite des arguments, ils sont fournis entre parenthèses ((...)) après le nom de la contrainte.If the constraint requires arguments, they're enclosed in parentheses ((...)) after the constraint name. Il est possible de spécifier plusieurs contraintes inline en ajoutant un autre signe deux-points (:) et le nom d’une autre contrainte.Multiple inline constraints can be specified by appending another colon (:) and constraint name.

Le nom de la contrainte et les arguments sont passés au service IInlineConstraintResolver pour créer une instance de IRouteConstraint à utiliser dans le traitement des URL.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. Par exemple, le modèle de routage blog/{article:minlength(10)} spécifie une contrainte minlength avec l’argument 10.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Pour plus d’informations sur les contraintes de route et pour obtenir la liste des contraintes fournies par le framework, consultez la section Informations de référence sur les contraintes de route.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Les paramètres de route peuvent également contenir des transformateurs de paramètre, qui transforment une valeur de paramètre lors de la génération des liens et de la mise en correspondance des actions et des pages avec les URL.Route parameters may also have parameter transformers, which transform a parameter's value when generating links and matching actions and pages to URLs. À l’instar des contraintes, les transformateurs de paramètre peuvent être ajoutés inline à un paramètre de routage en ajoutant un signe deux-points (:) et le nom du transformateur après le nom du paramètre de routage.Like constraints, parameter transformers can be added inline to a route parameter by adding a colon (:) and transformer name after the route parameter name. Par exemple, le modèle de routage blog/{article:slugify} spécifie un transformateur slugify.For example, the route template blog/{article:slugify} specifies a slugify transformer. Pour plus d’informations sur les transformateurs de paramètre, consultez la section Informations de référence sur les transformateurs de paramètre.For more information on parameter transformers, see the Parameter transformer reference section.

Le tableau suivant montre des exemples de modèles de route et leur comportement.The following table demonstrates example route templates and their behavior.

Modèle de routageRoute Template Exemple d’URI en correspondanceExample Matching URI URI de la requête…The request URI…
hello /hello Correspond seulement au chemin unique /hello.Only matches the single path /hello.
{Page=Home} / Correspond à Page et le définit sur Home.Matches and sets Page to Home.
{Page=Home} /Contact Correspond à Page et le définit sur Contact.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Mappe au contrôleur Products et à l’action List.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Mappe au contrôleur Products et à l’action Details (id défini sur 123).Maps to the Products controller and Details action (id set to 123).
{controller=Home}/{action=Index}/{id?} / Mappe au contrôleur Home et à la méthode Index (id est ignoré).Maps to the Home controller and Index method (id is ignored).

L’utilisation d’un modèle est généralement l’approche la plus simple pour le routage.Using a template is generally the simplest approach to routing. Il est également possible de spécifier des contraintes et des valeurs par défaut hors du modèle de routage.Constraints and defaults can also be specified outside the route template.

Conseil

Activez la journalisation pour voir comment les implémentations de routage intégrées, comme Route, établissent des correspondances avec les requêtes.Enable Logging to see how the built-in routing implementations, such as Route, match requests.

Noms de routage réservésReserved routing names

Les mots clés suivants sont des noms réservés qui ne peuvent pas être utilisés comme paramètres ou noms de routage :The following keywords are reserved names and can't be used as route names or parameters:

  • action
  • area
  • controller
  • handler
  • page

Informations de référence sur les contraintes de routageRoute constraint reference

Les contraintes de route s’exécutent quand une correspondance s’est produite pour l’URL entrante, et le chemin de l’URL est tokenisé en valeurs de route.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. En général, les contraintes de routage inspectent la valeur de route associée par le biais du modèle de routage, et créent une décision oui/non indiquant si la valeur est, ou non, acceptable.Route constraints generally inspect the route value associated via the route template and make a yes/no decision about whether or not the value is acceptable. Certaines contraintes de routage utilisent des données hors de la valeur de route pour déterminer si la requête peut être routée.Some route constraints use data outside the route value to consider whether the request can be routed. Par exemple, HttpMethodRouteConstraint peut accepter ou rejeter une requête en fonction de son verbe HTTP.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Les contraintes sont utilisées dans le routage des requêtes et la génération des liens.Constraints are used in routing requests and link generation.

Avertissement

N’utilisez pas de contraintes pour la validation des entrées.Don't use constraints for input validation. Si des contraintes sont utilisées pour la validation des entrées, une entrée non valide génère une réponse 404 - Introuvable au lieu d’une réponse 400 - Requête incorrecte avec un message d’erreur approprié.If constraints are used for input validation, invalid input results in a 404 - Not Found response instead of a 400 - Bad Request with an appropriate error message. Les contraintes de route sont utilisées pour lever l’ambiguïté entre des routes similaires, et non pas pour valider les entrées d’une route particulière.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

Le tableau suivant montre des exemples de contrainte de route et leur comportement attendu.The following table demonstrates example route constraints and their expected behavior.

ContrainteConstraint  ExempleExample Exemples de correspondancesExample matches NotesNotes
int {id:int} 123456789, -123456789123456789, -123456789 Correspond à n’importe quel entier.Matches any integer.
bool {active:bool} true, FALSEtrue, FALSE Correspond à true ou false .Matches true or false. Non-respect de la casse.Case-insensitive.
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Correspond à une DateTime valeur valide dans la culture dite indifférente.Matches a valid DateTime value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Correspond à une decimal valeur valide dans la culture dite indifférente.Matches a valid decimal value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une double valeur valide dans la culture dite indifférente.Matches a valid double value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une float valeur valide dans la culture dite indifférente.Matches a valid float value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638}CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Correspond à une Guid valeur valide.Matches a valid Guid value.
long {ticks:long} 123456789, -123456789123456789, -123456789 Correspond à une long valeur valide.Matches a valid long value.
minlength(value) {username:minlength(4)} Rick La chaîne doit comporter au moins 4 caractères.String must be at least 4 characters.
maxlength(value) {filename:maxlength(8)} MyFile La chaîne ne doit pas comporter plus de 8 caractères.String has maximum of 8 characters.
length(length) {filename:length(12)} somefile.txt La chaîne doit contenir exactement 12 caractères.String must be exactly 12 characters long.
length(min,max) {filename:length(8,16)} somefile.txt La chaîne doit être au moins égale à 8 et comporter jusqu’à 16 caractères.String must be at least 8 and has maximum of 16 characters.
min(value) {age:min(18)} 19 La valeur entière doit être au moins égale à 18.Integer value must be at least 18.
max(value) {age:max(120)} 91 Valeur entière maximale de 120.Integer value maximum of 120.
range(min,max) {age:range(18,120)} 91 La valeur entière doit être au moins égale à 18 et 120.Integer value must be at least 18 and maximum of 120.
alpha {name:alpha} Rick La chaîne doit comporter un ou plusieurs caractères alphabétiques a - z .String must consist of one or more alphabetical characters a-z. Non-respect de la casse.Case-insensitive.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 La chaîne doit correspondre à l’expression régulière.String must match the regular expression. Consultez les conseils relatifs à la définition d’une expression régulière.See tips about defining a regular expression.
required {name:required} Rick Permet d’appliquer qu’une valeur sans paramètre est présente pendant la génération de l’URL.Used to enforce that a non-parameter value is present during URL generation.

Il est possible d’appliquer plusieurs contraintes séparées par un point-virgule à un même paramètre.Multiple, colon-delimited constraints can be applied to a single parameter. Par exemple, la contrainte suivante limite un paramètre à une valeur entière supérieure ou égale à 1 :For example, the following constraint restricts a parameter to an integer value of 1 or greater:

[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

Avertissement

Les contraintes de routage qui vérifient que l’URL peut être convertie en type CLR (comme int ou DateTime) utilisent toujours la culture invariant.Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. ces contraintes partent du principe que l’URL n’est pas localisable.These constraints assume that the URL is non-localizable. Les contraintes de routage fournies par le framework ne modifient pas les valeurs stockées dans les valeurs de route.The framework-provided route constraints don't modify the values stored in route values. Toutes les valeurs de route analysées à partir de l’URL sont stockées sous forme de chaînes.All route values parsed from the URL are stored as strings. Par exemple, la contrainte float tente de convertir la valeur de route en valeur float, mais la valeur convertie est utilisée uniquement pour vérifier qu’elle peut être convertie en valeur float.For example, the float constraint attempts to convert the route value to a float, but the converted value is used only to verify it can be converted to a float.

Expressions régulièresRegular expressions

Le framework ASP.NET Core ajoute RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant au constructeur d’expression régulière.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Pour obtenir une description de ces membres, consultez RegexOptions.See RegexOptions for a description of these members.

Les expressions régulières utilisent des délimiteurs et des jetons similaires à ceux utilisés par le routage et le langage C#.Regular expressions use delimiters and tokens similar to those used by routing and the C# language. Les jetons d’expression régulière doivent être placés dans une séquence d’échappement.Regular expression tokens must be escaped. Pour utiliser l’expression régulière ^\d{3}-\d{2}-\d{4}$ dans le routage :To use the regular expression ^\d{3}-\d{2}-\d{4}$ in routing:

  • L’expression doit avoir les caractères de barre oblique inverse uniques \ fournis dans la chaîne sous la forme de caractères barre oblique inverse doubles \\ dans le code source.The expression must have the single backslash \ characters provided in the string as double backslash \\ characters in the source code.
  • L’expression régulière doit nous permettre d' \\ échapper le caractère d’échappement de la \ chaîne.The regular expression must us \\ in order to escape the \ string escape character.
  • L’expression régulière n’est pas nécessaire \\ lors de l’utilisation de littéraux de chaîne Verbatim.The regular expression doesn't require \\ when using verbatim string literals.

Pour échapper les caractères de délimiteur de paramètre de routage { , } ,, [ ] , doublez les caractères dans l’expression {{ , } [[ ]] ,,.To escape routing parameter delimiter characters {, }, [, ], double the characters in the expression {{, }, [[, ]]. Le tableau suivant montre une expression régulière et la version échappée :The following table shows a regular expression and the escaped version:

Expression régulièreRegular Expression Expression régulière en échappementEscaped Regular Expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Les expressions régulières utilisées dans le routage commencent souvent par le ^ caractère de signe insertion et correspondent à la position de départ de la chaîne.Regular expressions used in routing often start with the caret ^ character and match starting position of the string. Les expressions se terminent souvent par le $ caractère de signe dollar et la fin de la chaîne.The expressions often end with the dollar sign $ character and match end of the string. Les caractères ^ et $ garantissent que l’expression régulière établit une correspondance avec la totalité de la valeur du paramètre de route.The ^ and $ characters ensure that the regular expression match the entire route parameter value. Sans les caractères ^ et $, l’expression régulière peut correspondre à n’importe quelle sous-chaîne dans la chaîne, ce qui est souvent indésirable.Without the ^ and $ characters, the regular expression match any substring within the string, which is often undesirable. Le tableau suivant contient des exemples et explique pourquoi ils établissent ou non une correspondance.The following table provides examples and explains why they match or fail to match.

ExpressionExpression StringString CorrespondMatch CommentaireComment
[a-z]{2} hellohello OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} 123abc456123abc456 OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} mzmz OuiYes Correspondance avec l’expressionMatches expression
[a-z]{2} MZMZ OuiYes Non-respect de la casseNot case sensitive
^[a-z]{2}$ hellohello NonNo Voir ^ et $ ci-dessusSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NonNo Voir ^ et $ ci-dessusSee ^ and $ above

Pour plus d’informations sur la syntaxe des expressions régulières, consultez Expressions régulières du .NET Framework.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Pour contraindre un paramètre à un ensemble connu de valeurs possibles, utilisez une expression régulière.To constrain a parameter to a known set of possible values, use a regular expression. Par exemple, {action:regex(^(list|get|create)$)} établit une correspondance avec la valeur de route action uniquement pour list, get ou create.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Si elle est passée dans le dictionnaire de contraintes, la chaîne ^(list|get|create)$ est équivalente.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Les contraintes passées dans le dictionnaire de contraintes (c’est-à-dire qui ne sont pas inline dans un modèle) qui ne correspondent pas à l’une des contraintes connues sont également traitées comme des expressions régulières.Constraints that are passed in the constraints dictionary (not inline within a template) that don't match one of the known constraints are also treated as regular expressions.

Contraintes d’itinéraire personnaliséesCustom route constraints

Outre les contraintes d’itinéraire intégré, les contraintes d’itinéraire personnalisé peuvent être créées en implémentant l’interface IRouteConstraint.In addition to the built-in route constraints, custom route constraints can be created by implementing the IRouteConstraint interface. L’interface IRouteConstraint contient une méthode unique, Match, qui retourne true si la contrainte est satisfaite et false dans le cas contraire.The IRouteConstraint interface contains a single method, Match, which returns true if the constraint is satisfied and false otherwise.

Pour utiliser un IRouteConstraint personnalisé, le type de contrainte d’itinéraire doit être inscrit avec le ConstraintMap de l’application dans le conteneur de service de l’application.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the app's service container. Un ConstraintMap est un dictionnaire qui mappe les clés de contrainte d’itinéraire aux implémentations IRouteConstraint qui valident ces contraintes.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Le ConstraintMap d’une application peut être mis à jour dans Startup.ConfigureServices dans le cadre d’un appel services.AddRouting ou en configurant RouteOptions directement avec services.Configure<RouteOptions>.An app's ConstraintMap can be updated in Startup.ConfigureServices either as part of a services.AddRouting call or by configuring RouteOptions directly with services.Configure<RouteOptions>. Par exemple :For example:

services.AddRouting(options =>
{
    options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
});

La contrainte peut ensuite être appliquée aux itinéraires de la manière habituelle, en utilisant le nom spécifié lors de l’inscription du type de contrainte.The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. Par exemple :For example:

[HttpGet("{id:customName}")]
public ActionResult<string> Get(string id)

Informations de référence sur le transformateur de paramètreParameter transformer reference

Transformateurs de paramètre :Parameter transformers:

  • Sont exécutés lors de la génération d’un lien pour un Route.Execute when generating a link for a Route.
  • Implémentez Microsoft.AspNetCore.Routing.IOutboundParameterTransformer.Implement Microsoft.AspNetCore.Routing.IOutboundParameterTransformer.
  • Sont configurés à l’aide de ConstraintMap.Are configured using ConstraintMap.
  • Prennent la valeur de routage du paramètre et la convertissent en une nouvelle valeur de chaîne.Take the parameter's route value and transform it to a new string value.
  • Aboutissent à l’utilisation de la valeur transformée dans le lien généré.Result in using the transformed value in the generated link.

Par exemple, un transformateur de paramètre slugify personnalisé dans le modèle d’itinéraire blog\{article:slugify} avec Url.Action(new { article = "MyTestArticle" }) génère blog\my-test-article.For example, a custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article.

Pour utiliser un transformateur de paramètre dans un modèle d’itinéraire, configurez-le d’abord en utilisant ConstraintMap dans Startup.ConfigureServices :To use a parameter transformer in a route pattern, configure it first using ConstraintMap in Startup.ConfigureServices:

services.AddRouting(options =>
{
    // Replace the type and the name used to refer to it with your own
    // IOutboundParameterTransformer implementation
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

Les transformateurs de paramètre sont utilisés par le framework pour transformer l’URI où un point de terminaison est résolu.Parameter transformers are used by the framework to transform the URI where an endpoint resolves. Par exemple, ASP.NET Core MVC utilise des transformateurs de paramètre pour convertir la valeur de routage utilisée et la faire correspondre à un area, controller, action et page.For example, ASP.NET Core MVC uses parameter transformers to transform the route value used to match an area, controller, action, and page.

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

Avec la route précédente, l’action SubscriptionManagementController.GetAll est mise en correspondance avec l’URI /subscription-management/get-all.With the preceding route, the action SubscriptionManagementController.GetAll is matched with the URI /subscription-management/get-all. Un transformateur de paramètre ne modifie pas les valeurs de routage utilisées pour générer un lien.A parameter transformer doesn't change the route values used to generate a link. Par exemple, Url.Action("GetAll", "SubscriptionManagement") produit /subscription-management/get-all.For example, Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core fournit des conventions d’API pour l’utilisation des transformateurs de paramètre avec des routages générés :ASP.NET Core provides API conventions for using a parameter transformers with generated routes:

  • La convention de l’API Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention est fournie avec ASP.NET Core MVC.ASP.NET Core MVC has the Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention API convention. Cette convention applique un transformateur de paramètre spécifié à tous les routages d’attributs dans l’application.This convention applies a specified parameter transformer to all attribute routes in the app. Le transformateur de paramètre transforme les jetons de routage d’attribut quand ils sont remplacés.The parameter transformer transforms attribute route tokens as they are replaced. Pour plus d’informations, consultez Utiliser un transformateur de paramètre pour personnaliser le remplacement des jetons.For more information, see Use a parameter transformer to customize token replacement.
  • Razor Les pages possèdent la Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention Convention d’API.Razor Pages has the Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention API convention. Cette Convention applique un transformateur de paramètre spécifié à toutes les Razor pages découvertes automatiquement.This convention applies a specified parameter transformer to all automatically discovered Razor Pages. Le transformateur de paramètres transforme les segments de nom de fichier et de dossier des Razor itinéraires de pages.The parameter transformer transforms the folder and file name segments of Razor Pages routes. Pour plus d’informations, consultez Utiliser un transformateur de paramètre pour personnaliser les routages de pages.For more information, see Use a parameter transformer to customize page routes.

Informations de référence sur la génération d’URLURL generation reference

L’exemple suivant montre comment générer un lien vers une route selon un dictionnaire de valeurs de route et un RouteCollection données.The following example shows how to generate a link to a route given a dictionary of route values and a RouteCollection.

app.Run(async (context) =>
{
    var dictionary = new RouteValueDictionary
    {
        { "operation", "create" },
        { "id", 123}
    };

    var vpc = new VirtualPathContext(context, null, dictionary, 
        "Track Package Route");
    var path = routes.GetVirtualPath(vpc).VirtualPath;

    context.Response.ContentType = "text/html";
    await context.Response.WriteAsync("Menu<hr/>");
    await context.Response.WriteAsync(
        $"<a href='{path}'>Create Package 123</a><br/>");
});

Le VirtualPath généré à la fin de l’exemple précédent est /package/create/123.The VirtualPath generated at the end of the preceding sample is /package/create/123. Le dictionnaire fournit les valeurs de route operation et id du modèle « Suivi de package de route », package/{operation}/{id}.The dictionary supplies the operation and id route values of the "Track Package Route" template, package/{operation}/{id}. Pour plus d’informations, consultez l’exemple de code dans la section Utilisation du middleware de routage ou l’exemple d’application.For details, see the sample code in the Use Routing Middleware section or the sample app.

Le deuxième paramètre pour le constructeur VirtualPathContext est une collection de valeurs ambiantes.The second parameter to the VirtualPathContext constructor is a collection of ambient values. Les valeurs ambiantes sont pratiques à utiliser, car elles limitent le nombre de valeurs qu’un développeur doit spécifier dans un contexte de requête.Ambient values are convenient to use because they limit the number of values a developer must specify within a request context. Les valeurs de route actuelles de la requête actuelle sont considérées comme des valeurs ambiantes pour la génération de liens.The current route values of the current request are considered ambient values for link generation. Dans l’action About de HomeController d’une application ASP.NET Core MVC, vous n’avez pas besoin de spécifier la valeur de route du contrôleur pour créer un lien vers l’action Index : la valeur ambiante de Home est utilisée.In an ASP.NET Core MVC app's About action of the HomeController, you don't need to specify the controller route value to link to the Index action—the ambient value of Home is used.

Les valeurs ambiantes qui ne correspondent pas à un paramètre sont ignorées.Ambient values that don't match a parameter are ignored. Les valeurs ambiantes sont également ignorées quand une valeur explicitement fournie remplace la valeur ambiante.Ambient values are also ignored when an explicitly provided value overrides the ambient value. La mise en correspondance se produit de gauche à droite dans l’URL.Matching occurs from left to right in the URL.

Les valeurs fournies explicitement mais qui n’ont pas de correspondance avec un segment de la route sont ajoutées à la chaîne de requête.Values explicitly provided but that don't match a segment of the route are added to the query string. Le tableau suivant présente le résultat en cas d’utilisation du modèle de routage {controller}/{action}/{id?}.The following table shows the result when using the route template {controller}/{action}/{id?}.

Valeurs ambiantesAmbient Values Valeurs explicitesExplicit Values RésultatResult
controller = "Home"controller = "Home" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" controller = "Order", action = "About"controller = "Order", action = "About" /Order/About
controller = "Home", color = "Red"controller = "Home", color = "Red" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" action = "About", color = "Red"action = "About", color = "Red" /Home/About?color=Red

Si une route a une valeur par défaut qui ne correspond pas à un paramètre et que cette valeur est explicitement fournie, elle doit correspondre à la valeur par défaut :If a route has a default value that doesn't correspond to a parameter and that value is explicitly provided, it must match the default value:

routes.MapRoute("blog_route", "blog/{*slug}",
    defaults: new { controller = "Blog", action = "ReadPost" });

La génération de liens génère un lien pour cette route seulement quand les valeurs correspondantes pour controller et pour action sont fournies.Link generation only generates a link for this route when the matching values for controller and action are provided.

Segments complexesComplex segments

Les segments complexes (par exemple, [Route("/x{token}y")]) sont traités par la mise en correspondance des littéraux de droite à gauche de manière non gourmande.Complex segments (for example [Route("/x{token}y")]) are processed by matching up literals from right to left in a non-greedy way. Consultez ce code pour obtenir une explication détaillée de la façon dont les segments complexes sont mis en correspondance.See this code for a detailed explanation of how complex segments are matched. L’exemple de code n’est pas utilisé par ASP.NET Core, mais il fournit une bonne explication des segments complexes.The code sample is not used by ASP.NET Core, but it provides a good explanation of complex segments.

Le routage est responsable du mappage des URI des requêtes aux gestionnaires de routage et de la distribution des requêtes entrantes.Routing is responsible for mapping request URIs to route handlers and dispatching an incoming requests. Les routes sont définies dans l’application et configurées au démarrage de l’application.Routes are defined in the app and configured when the app starts. Une route peut éventuellement extraire des valeurs de l’URL contenue dans la requête, et ces valeurs peuvent ensuite être utilisées pour le traitement de la requête.A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. En utilisant des routes configurées à partir de l’application, le routage est en mesure de générer des URL qui mappent à des gestionnaires de routage.Using configured routes from the app, routing is able to generate URLs that map to route handlers.

Pour utiliser les scénarios de routage les plus récents dans ASP.NET Core 2.1, spécifiez la version de compatibilité à l’inscription des services MVC dans Startup.ConfigureServices :To use the latest routing scenarios in ASP.NET Core 2.1, specify the compatibility version to the MVC services registration in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Important

Ce document traite du routage ASP.NET Core de bas niveau.This document covers low-level ASP.NET Core routing. Pour plus d’informations sur le routage ASP.NET Core MVC, consultez Routage vers les actions du contrôleur dans ASP.NET Core.For information on ASP.NET Core MVC routing, see Routage vers les actions du contrôleur dans ASP.NET Core. Pour plus d’informations sur les conventions de routage dans les Razor pages, consultez Razor Conventions de routage et d’application des pages dans ASP.NET Core .For information on routing conventions in Razor Pages, see Razor Conventions de routage et d’application des pages dans ASP.NET Core.

Afficher ou télécharger l’exemple de code (procédure de téléchargement)View or download sample code (how to download)

Concepts de base du routageRouting basics

La plupart des applications doivent choisir un schéma de routage de base et descriptif pour que les URL soient lisibles et explicites.Most apps should choose a basic and descriptive routing scheme so that URLs are readable and meaningful. La route conventionnelle par défaut {controller=Home}/{action=Index}/{id?} :The default conventional route {controller=Home}/{action=Index}/{id?}:

  • Prend en charge un schéma de routage de base et descriptif.Supports a basic and descriptive routing scheme.
  • Est un point de départ pratique pour les applications basées sur une interface utilisateur.Is a useful starting point for UI-based apps.

Les développeurs ajoutent fréquemment des routes laconiques supplémentaires aux zones à trafic élevé de l’application dans des situations particulières (par exemple des points de terminaison de blog ou d’e-commerce) en utilisant le routage d’attributs ou des routes conventionnelles dédiées.Developers commonly add additional terse routes to high-traffic areas of an app in specialized situations (for example, blog and ecommerce endpoints) using attribute routing or dedicated conventional routes.

Les API web doivent utiliser le routage d’attributs pour modéliser les fonctionnalités de l’application sous la forme d’un ensemble de ressources dans lequel les opérations sont représentées par des verbes HTTP.Web APIs should use attribute routing to model the app's functionality as a set of resources where operations are represented by HTTP verbs. Cela signifie que plusieurs opérations (comme GET et POST) sur la même ressource logique utilisent la même URL.This means that many operations (for example, GET, POST) on the same logical resource will use the same URL. Le routage d’attributs fournit le niveau de contrôle nécessaire pour concevoir avec soin la disposition des points de terminaison publics d’une API.Attribute routing provides a level of control that's needed to carefully design an API's public endpoint layout.

Razor Pages les applications utilisent le routage conventionnel par défaut pour servir des ressources nommées dans le dossier pages d’une application.Razor Pages apps use default conventional routing to serve named resources in the Pages folder of an app. Des conventions supplémentaires vous permettent de personnaliser le Razor comportement de routage des pages.Additional conventions are available that allow you to customize Razor Pages routing behavior. Pour plus d’informations, consultez Présentation Razor des pages dans ASP.net Core et Razor Conventions de routage et d’application des pages dans ASP.NET Core.For more information, see Présentation Razor des pages dans ASP.net Core and Razor Conventions de routage et d’application des pages dans ASP.NET Core.

La prise en charge de la génération d’URL permet de développer l’application sans coder en dur les URL pour lier l’application.URL generation support allows the app to be developed without hard-coding URLs to link the app together. Cette prise en charge permet de commencer avec une configuration de routage de base, puis de modifier les routes une fois que la disposition des ressources de l’application est déterminée.This support allows for starting with a basic routing configuration and modifying the routes after the app's resource layout is determined.

Le routage utilise des implémentations d’itinéraires de IRouter à :Routing uses routes implementations of IRouter to:

  • Mapper les requêtes entrantes à des gestionnaires de routage.Map incoming requests to route handlers.
  • Générer les URL utilisées dans les réponses.Generate the URLs used in responses.

Par défaut, une application a une seule collection de routes.By default, an app has a single collection of routes. Quand une requête arrive, les routes de la collection sont traitées dans l’ordre où elles se trouvent dans la collection.When a request arrives, the routes in the collection are processed in the order that they exist in the collection. Le framework tente de mettre en correspondance l’URL d’une requête entrante avec une route de la collection en appelant la méthode RouteAsync sur chaque route de la collection.The framework attempts to match an incoming request URL to a route in the collection by calling the RouteAsync method on each route in the collection. Une réponse peut utiliser le routage pour générer des URL (par exemple pour la redirection ou pour des liens) en fonction des informations des routes et éviter ainsi les URL codées en dur, ce qui facilite la maintenance.A response can use routing to generate URLs (for example, for redirection or links) based on route information and thus avoid hard-coded URLs, which helps maintainability.

Le système de routage a les caractéristiques suivantes :The routing system has the following characteristics:

  • Une syntaxe des modèles de route est utilisée pour définir des routes avec des paramètres de route tokenisés.Route template syntax is used to define routes with tokenized route parameters.
  • La configuration de points de terminaison de style conventionnel et de style « attribut » est autorisée.Conventional-style and attribute-style endpoint configuration is permitted.
  • IRouteConstraint est utilisé pour déterminer si un paramètre d’URL contient une valeur valide pour une contrainte de point de terminaison donné.IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.
  • Les modèles d’application, tels que MVC/ Razor pages, inscrivent tous leurs itinéraires, qui ont une implémentation prévisible des scénarios de routage.App models, such as MVC/Razor Pages, register all of their routes, which have a predictable implementation of routing scenarios.
  • Une réponse peut utiliser le routage pour générer des URL (par exemple pour la redirection ou pour des liens) en fonction des informations des routes et éviter ainsi les URL codées en dur, ce qui facilite la maintenance.A response can use routing to generate URLs (for example, for redirection or links) based on route information and thus avoid hard-coded URLs, which helps maintainability.
  • La génération d’URL est basée sur des routes, qui prennent en charge l’extensibilité arbitraire.URL generation is based on routes, which support arbitrary extensibility. IUrlHelper offre des méthodes pour générer des URL.IUrlHelper offers methods to build URLs.

Le routage est connecté au pipeline de l’intergiciel (middleware) par la classe RouterMiddleware.Routing is connected to the middleware pipeline by the RouterMiddleware class. ASP.net Core MVC ajoute le routage au pipeline de l’intergiciel (middleware) dans le cadre de sa configuration et gère le routage dans les applications MVC et Razor pages.ASP.NET Core MVC adds routing to the middleware pipeline as part of its configuration and handles routing in MVC and Razor Pages apps. Pour découvrir comment utiliser le routage en tant que composant autonome, consultez la section Utiliser le middleware de routage.To learn how to use routing as a standalone component, see the Use Routing Middleware section.

Correspondance d’URLURL matching

La correspondance d’URL est le processus par lequel le routage distribue une requête entrante à un gestionnaire.URL matching is the process by which routing dispatches an incoming request to a handler. Ce processus est basé sur des données présentes dans le chemin de l’URL, mais il peut être étendu pour prendre en compte toutes les données de la requête.This process is based on data in the URL path but can be extended to consider any data in the request. La possibilité de distribuer des requêtes à des gestionnaires distincts est essentielle pour adapter la taille et la complexité d’une application.The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

Les requêtes entrantes entrent dans RouterMiddleware, qui appelle la méthode RouteAsync sur chaque route dans l’ordre.Incoming requests enter the RouterMiddleware, which calls the RouteAsync method on each route in sequence. L’instance IRouter détermine s’il faut gérer la requête en affectant à RouteContext.Handler un RequestDelegate non null.The IRouter instance chooses whether to handle the request by setting the RouteContext.Handler to a non-null RequestDelegate. Si une route définit un gestionnaire pour la requête, le traitement de la route s’arrête et le gestionnaire est appelé pour traiter la requête.If a route sets a handler for the request, route processing stops, and the handler is invoked to process the request. Si aucun gestionnaire de routage n’est trouvé pour traiter la requête, le middleware passe la requête au middleware suivant dans le pipeline de requête.If no route handler is found to process the request, the middleware hands the request off to the next middleware in the request pipeline.

L’entrée principale de RouteAsync est le RouteContext.HttpContext associé à la requête actuelle.The primary input to RouteAsync is the RouteContext.HttpContext associated with the current request. RouteContext.Handler et RouteContext.RouteData sont des sorties définies après la mise en correspondance d’une route.The RouteContext.Handler and RouteContext.RouteData are outputs set after a route is matched.

Une correspondance qui appelle RouteAsync définit également les propriétés de RouteContext.RouteData sur des valeurs appropriées en fonction du traitement des requêtes effectué jusqu’à présent.A match that calls RouteAsync also sets the properties of the RouteContext.RouteData to appropriate values based on the request processing performed thus far.

RouteData.Values est un dictionnaire de valeurs de route produites à partir de la route.RouteData.Values is a dictionary of route values produced from the route. Ces valeurs sont généralement déterminées en décomposant l’URL en jetons. Elles peuvent être utilisées pour accepter l’entrée d’utilisateur ou pour prendre d’autres décisions relatives à la distribution à l’intérieur de l’application.These values are usually determined by tokenizing the URL and can be used to accept user input or to make further dispatching decisions inside the app.

RouteData.DataTokens est un conteneur de propriétés des données supplémentaires associées à la route mise en correspondance.RouteData.DataTokens is a property bag of additional data related to the matched route. Les DataTokens sont fournis pour prendre en charge l’association de données d’état à chaque route, de façon que l’application puisse prendre des décisions en fonction de la route avec laquelle la correspondance a été établie.DataTokens are provided to support associating state data with each route so that the app can make decisions based on which route matched. Ces valeurs sont définies par le développeur et n’affectent pas le comportement du routage de quelque manière que ce soit.These values are developer-defined and do not affect the behavior of routing in any way. De plus, les valeurs dissimulées dans RouteData.DataTokens peuvent être de n’importe quel type, contrairement aux valeurs RouteData.Values, qui doivent être convertibles en chaînes et à partir de chaînes.Additionally, values stashed in RouteData.DataTokens can be of any type, in contrast to RouteData.Values, which must be convertible to and from strings.

RouteData.Routers est une liste des routes qui ont participé à la mise en correspondance correcte de la requête.RouteData.Routers is a list of the routes that took part in successfully matching the request. Les routes peuvent être imbriquées les unes dans les autres.Routes can be nested inside of one another. La propriété Routers reflète le chemin à travers l’arborescence logique des routes qui ont généré une correspondance.The Routers property reflects the path through the logical tree of routes that resulted in a match. En général le premier élément de Routers est la collection de routes et il doit être utilisé pour la génération d’URL.Generally, the first item in Routers is the route collection and should be used for URL generation. Le dernier élément de Routers est le gestionnaire de routage avec lequel la correspondance a été établie.The last item in Routers is the route handler that matched.

Génération d’URLURL generation

La génération d’URL est le processus par lequel le routage peut créer un chemin d’URL basé sur un ensemble de valeurs de route.URL generation is the process by which routing can create a URL path based on a set of route values. Ceci permet une séparation logique entre les gestionnaires de routes et les URL qui y accèdent.This allows for a logical separation between route handlers and the URLs that access them.

La génération d’URL suit un processus itératif similaire, mais elle commence par un appel du code utilisateur ou de framework à la méthode GetVirtualPath de la collection de routes.URL generation follows a similar iterative process, but it starts with user or framework code calling into the GetVirtualPath method of the route collection. La méthode GetVirtualPath de chaque route est appelée en séquence jusqu’à ce qu’un VirtualPathData non null soit retourné.Each route has its GetVirtualPath method called in sequence until a non-null VirtualPathData is returned.

Les entrées principales dans GetVirtualPath sont les suivantes :The primary inputs to GetVirtualPath are:

Les routes utilisent principalement les valeurs de routage fournies par Values et par AmbientValues pour décider où il est possible de générer une URL et quelles sont les valeurs à inclure.Routes primarily use the route values provided by Values and AmbientValues to decide whether it's possible to generate a URL and what values to include. Les AmbientValues sont l’ensemble des valeurs de route produites à partir de la mise en correspondance de la requête actuelle.The AmbientValues are the set of route values that were produced from matching the current request. En revanche, les Values sont les valeurs de route qui spécifient la façon de générer l’URL souhaitée pour l’opération actuelle.In contrast, Values are the route values that specify how to generate the desired URL for the current operation. HttpContext est fourni au cas où une route aurait besoin d’obtenir des services ou des données supplémentaires associés au contexte actuel.The HttpContext is provided in case a route should obtain services or additional data associated with the current context.

Conseil

Considérez VirtualPathContext.Values comme un ensemble de remplacements pour VirtualPathContext.AmbientValues.Think of VirtualPathContext.Values as a set of overrides for the VirtualPathContext.AmbientValues. La génération d’URL tente de réutiliser des valeurs de route de la requête actuelle afin de générer les URL pour des liens utilisant la même route ou les mêmes valeurs de route.URL generation attempts to reuse route values from the current request to generate URLs for links using the same route or route values.

La sortie de GetVirtualPath est un VirtualPathData.The output of GetVirtualPath is a VirtualPathData. VirtualPathData est l’équivalent de RouteData.VirtualPathData is a parallel of RouteData. VirtualPathData contient le VirtualPath de l’URL de sortie et des propriétés supplémentaires qui doivent être définies par la route.VirtualPathData contains the VirtualPath for the output URL and some additional properties that should be set by the route.

La propriété VirtualPathData.VirtualPath contient le chemin virtuel produit par la route.The VirtualPathData.VirtualPath property contains the virtual path produced by the route. Selon vos besoins, vous devrez peut-être traiter plus avant le chemin.Depending on your needs, you may need to process the path further. Si vous souhaitez afficher l’URL générée au format HTML, ajoutez un préfixe au chemin de base de l’application.If you want to render the generated URL in HTML, prepend the base path of the app.

VirtualPathData.Router est une référence à la route qui a généré avec succès l’URL.The VirtualPathData.Router is a reference to the route that successfully generated the URL.

La propriété VirtualPathData.DataTokens est un dictionnaire de données supplémentaires relatives à la route qui a généré l’URL.The VirtualPathData.DataTokens properties is a dictionary of additional data related to the route that generated the URL. Il s’agit de l’équivalent de RouteData.DataTokens.This is the parallel of RouteData.DataTokens.

Créer des itinérairesCreate routes

Le routage fournit la classe Route comme implémentation standard d’IRouter.Routing provides the Route class as the standard implementation of IRouter. Route utilise la syntaxe des modèles de routage pour définir des modèles à mettre en correspondance avec le chemin d’URL quand RouteAsync est appelé.Route uses the route template syntax to define patterns to match against the URL path when RouteAsync is called. Route utilise le même modèle de routage pour générer une URL quand GetVirtualPath est appelé.Route uses the same route template to generate a URL when GetVirtualPath is called.

La plupart des applications créent des routes en appelant MapRoute ou l’une des méthodes d’extension similaires définies sur IRouteBuilder.Most apps create routes by calling MapRoute or one of the similar extension methods defined on IRouteBuilder. Toutes les méthodes d’extension de IRouteBuilder créent une instance de Route et l’ajoutent à la collection de routes.Any of the IRouteBuilder extension methods create an instance of Route and add it to the route collection.

MapRoute n’accepte pas de paramètre de gestionnaire de routage.MapRoute doesn't accept a route handler parameter. MapRoute ajoute uniquement des routes gérées par DefaultHandler.MapRoute only adds routes that are handled by the DefaultHandler. Le gestionnaire par défaut est un IRouter, et le gestionnaire est susceptible de ne pas traiter la requête.The default handler is an IRouter, and the handler might not handle the request. Par exemple, ASP.NET Core MVC est généralement configuré comme gestionnaire par défaut qui gère uniquement les requêtes correspondant à un contrôleur et une action disponibles.For example, ASP.NET Core MVC is typically configured as a default handler that only handles requests that match an available controller and action. Pour plus d’informations sur le routage dans MVC, consultez Routage vers les actions du contrôleur dans ASP.NET Core.To learn more about routing in MVC, see Routage vers les actions du contrôleur dans ASP.NET Core.

L’exemple de code suivant est un exemple d’appel à MapRoute utilisé par une définition de route ASP.NET Core MVC classique :The following code example is an example of a MapRoute call used by a typical ASP.NET Core MVC route definition:

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

Ce modèle établit une correspondance avec un chemin d’URL et extrait les valeurs de route .This template matches a URL path and extracts the route values. Par exemple, le chemin /Products/Details/17 génère les valeurs de route suivantes : { controller = Products, action = Details, id = 17 }.For example, the path /Products/Details/17 generates the following route values: { controller = Products, action = Details, id = 17 }.

Les valeurs de route sont déterminées en divisant le chemin d’URL en segments et en mettant en correspondance chaque segment avec le nom des paramètres de routage dans le modèle de routage.Route values are determined by splitting the URL path into segments and matching each segment with the route parameter name in the route template. Les paramètres de routage sont nommés.Route parameters are named. Vous définissez des paramètres en plaçant leur nom entre des accolades { ... }.The parameters defined by enclosing the parameter name in braces { ... }.

Le modèle précédent peut également mettre en correspondance le chemin d’URL / et produire les valeurs { controller = Home, action = Index }.The preceding template could also match the URL path / and produce the values { controller = Home, action = Index }. Cela s’explique par le fait que les paramètres de routage {controller} et {action} ont des valeurs par défaut et que le paramètre de routage id est facultatif.This occurs because the {controller} and {action} route parameters have default values and the id route parameter is optional. Un signe égal (=) suivi d’une valeur après le nom du paramètre de routage définit une valeur par défaut pour le paramètre.An equals sign (=) followed by a value after the route parameter name defines a default value for the parameter. Un point d’interrogation (?) après le nom du paramètre de routage définit un paramètre facultatif.A question mark (?) after the route parameter name defines an optional parameter.

Les paramètres de routage ayant une valeur par défaut produisent toujours une valeur de routage quand la route correspond.Route parameters with a default value always produce a route value when the route matches. Les paramètres facultatifs ne produisent pas de valeur de route s’il n’y a pas de segment de chemin d’URL correspondant.Optional parameters don't produce a route value if there is no corresponding URL path segment. Pour obtenir une description complète des scénarios et de la syntaxe des modèles de routage, consultez la section Informations de référence sur les modèles de routage.See the Route template reference section for a thorough description of route template scenarios and syntax.

Dans l’exemple suivant, la définition du paramètre de route {id:int} définit une contrainte de route pour le paramètre de route id :In the following example, the route parameter definition {id:int} defines a route constraint for the id route parameter:

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

Ce modèle établit une correspondance avec un chemin d’URL comme /Products/Details/17, mais pas /Products/Details/Apples.This template matches a URL path like /Products/Details/17 but not /Products/Details/Apples. Les contraintes de routage implémentent IRouteConstraint et inspectent les valeurs de route pour les vérifier.Route constraints implement IRouteConstraint and inspect route values to verify them. Dans cet exemple, la valeur de route id doit être convertible en entier.In this example, the route value id must be convertible to an integer. Pour obtenir une explication des contraintes de route fournies par le framework, consultez Informations de référence sur les contraintes de route.See route-constraint-reference for an explanation of route constraints provided by the framework.

Des surcharges supplémentaires de MapRoute acceptent des values pour constraints, dataTokens et defaults.Additional overloads of MapRoute accept values for constraints, dataTokens, and defaults. L’utilisation classique de ces paramètres consiste à passer un objet typé anonymement, où les noms des propriétés du type anonyme correspondent aux noms de paramètre de routage.The typical usage of these parameters is to pass an anonymously typed object, where the property names of the anonymous type match route parameter names.

Les exemples de MapRoute suivants créent des routes équivalentes :The following MapRoute examples create equivalent routes:

routes.MapRoute(
    name: "default_route",
    template: "{controller}/{action}/{id?}",
    defaults: new { controller = "Home", action = "Index" });

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

Conseil

La syntaxe inline pour la définition des contraintes et des valeurs par défaut peut être pratique pour les routes simples.The inline syntax for defining constraints and defaults can be convenient for simple routes. Cependant, certains scénarios, comme les jetons de données, ne sont pas pris en charge par la syntaxe inline.However, there are scenarios, such as data tokens, that aren't supported by inline syntax.

L’exemple suivant montre quelques autres scénarios :The following example demonstrates a few additional scenarios:

routes.MapRoute(
    name: "blog",
    template: "Blog/{*article}",
    defaults: new { controller = "Blog", action = "ReadArticle" });

Le modèle précédent établit une correspondance avec un chemin d’URL comme /Blog/All-About-Routing/Introduction et extrait les valeurs { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }.The preceding template matches a URL path like /Blog/All-About-Routing/Introduction and extracts the values { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }. Les valeurs de route par défaut pour controller et action sont produites par la route, même s’il n’existe aucun paramètre de routage correspondant dans le modèle.The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. Il est possible de spécifier des valeurs par défaut dans le modèle de route.Default values can be specified in the route template. Le paramètre de route article est défini comme *passe-partout * par la présence d’un astérisque (*) avant le nom du paramètre de route.The article route parameter is defined as a catch-all by the appearance of an asterisk (*) before the route parameter name. Les paramètres de routage fourre-tout capturent le reste du chemin d’URL et peuvent également établir une correspondance avec la chaîne vide.Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

L’exemple suivant ajoute des contraintes de route et des jetons de données :The following example adds route constraints and data tokens:

routes.MapRoute(
    name: "us_english_products",
    template: "en-US/Products/{id}",
    defaults: new { controller = "Products", action = "Details" },
    constraints: new { id = new IntRouteConstraint() },
    dataTokens: new { locale = "en-US" });

Le modèle précédent établit une correspondance avec un chemin d’URL comme /en-US/Products/5, et extrait les valeurs { controller = Products, action = Details, id = 5 } et les jetons de données { locale = en-US }.The preceding template matches a URL path like /en-US/Products/5 and extracts the values { controller = Products, action = Details, id = 5 } and the data tokens { locale = en-US }.

Jetons Windows de variables locales

Génération d’URL de classe de routeRoute class URL generation

La classe Route peut également effectuer une génération d’URL en combinant un ensemble de valeurs de route et son modèle de routage.The Route class can also perform URL generation by combining a set of route values with its route template. Il s’agit logiquement du processus inverse de la mise en correspondance du chemin d’URL.This is logically the reverse process of matching the URL path.

Conseil

Pour mieux comprendre la génération d’URL, imaginez l’URL que vous voulez générer, puis pensez à la façon dont un modèle de routage établirait une correspondance avec cette URL.To better understand URL generation, imagine what URL you want to generate and then think about how a route template would match that URL. Quelles valeurs seraient produites ?What values would be produced? Cela équivaut approximativement à la façon dont la génération d’URL fonctionne dans la classe Route.This is the rough equivalent of how URL generation works in the Route class.

L’exemple suivant utilise une route par défaut ASP.NET Core MVC générale :The following example uses a general ASP.NET Core MVC default route:

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

Avec les valeurs de route { controller = Products, action = List }, l’URL /Products/List est générée.With the route values { controller = Products, action = List }, the URL /Products/List is generated. Les valeurs de route remplacent les paramètres de routage correspondant pour former le chemin d’URL.The route values are substituted for the corresponding route parameters to form the URL path. Dans la mesure où id est un paramètre de route facultatif, l’URL est générée correctement sans valeur pour id.Since id is an optional route parameter, the URL is successfully generated without a value for id.

Avec les valeurs de route { controller = Home, action = Index }, l’URL / est générée.With the route values { controller = Home, action = Index }, the URL / is generated. Les valeurs de route fournies correspondent aux valeurs par défaut, et les segments correspondant aux valeurs par défaut peuvent être omis sans risque.The provided route values match the default values, and the segments corresponding to the default values are safely omitted.

Les deux URL générées effectuent un aller-retour avec la définition de route suivante (/Home/Index et /), et produisent les mêmes valeurs de route que celles utilisées pour générer l’URL.Both URLs generated round-trip with the following route definition (/Home/Index and /) produce the same route values that were used to generate the URL.

Notes

Pour générer des URL, une application utilisant ASP.NET Core MVC doit utiliser UrlHelper au lieu d’effectuer un appel directement dans le routage.An app using ASP.NET Core MVC should use UrlHelper to generate URLs instead of calling into routing directly.

Pour plus d’informations sur la génération d’URL, consultez la section Informations de référence sur la génération d’URL.For more information on URL generation, see the Url generation reference section.

Utiliser l’intergiciel (middleware) de routageUse routing middleware

Référencez le métapackage Microsoft.AspNetCore.App dans le fichier projet de l’application.Reference the Microsoft.AspNetCore.App metapackage in the app's project file.

Ajoutez le routage au conteneur de service dans Startup.ConfigureServices :Add routing to the service container in Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting();
}

Les routes doivent être configurées dans la méthode Startup.Configure.Routes must be configured in the Startup.Configure method. L’exemple d’application utilise les API suivantes :The sample app uses the following APIs:

var trackPackageRouteHandler = new RouteHandler(context =>
{
    var routeValues = context.GetRouteData().Values;
    return context.Response.WriteAsync(
        $"Hello! Route values: {string.Join(", ", routeValues)}");
});

var routeBuilder = new RouteBuilder(app, trackPackageRouteHandler);

routeBuilder.MapRoute(
    "Track Package Route",
    "package/{operation:regex(^track|create$)}/{id:int}");

routeBuilder.MapGet("hello/{name}", context =>
{
    var name = context.GetRouteValue("name");
    // The route handler when HTTP GET "hello/<anything>" matches
    // To match HTTP GET "hello/<anything>/<anything>, 
    // use routeBuilder.MapGet("hello/{*name}"
    return context.Response.WriteAsync($"Hi, {name}!");
});

var routes = routeBuilder.Build();
app.UseRouter(routes);

Le tableau suivant montre les réponses avec les URI donnés.The following table shows the responses with the given URIs.

URIURI responseResponse
/package/create/3 Hello!Hello! Valeurs de route : [operation, create], [id, 3]Route values: [operation, create], [id, 3]
/package/track/-3 Hello!Hello! Valeurs de route : [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/-3/ Hello!Hello! Valeurs de route : [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/ La requête passe à travers ceci, aucune correspondance.The request falls through, no match.
GET /hello/Joe Hi, Joe!Hi, Joe!
POST /hello/Joe La requête passe à travers ceci, correspondance seulement avec HTTP GET.The request falls through, matches HTTP GET only.
GET /hello/Joe/Smith La requête passe à travers ceci, aucune correspondance.The request falls through, no match.

Si vous configurez une seule route, appelez UseRouter en passant une instance IRouter.If you're configuring a single route, call UseRouter passing in an IRouter instance. Vous n’avez pas besoin d’utiliser RouteBuilder.You won't need to use RouteBuilder.

Le framework fournit un ensemble de méthodes d’extension pour la création de routes (RequestDelegateRouteBuilderExtensions) :The framework provides a set of extension methods for creating routes (RequestDelegateRouteBuilderExtensions):

Certaines des méthodes listées, comme MapGet, nécessitent un RequestDelegate.Some of listed methods, such as MapGet, require a RequestDelegate. RequestDelegate est utilisé comme gestionnaire de routage quand une correspondance est trouvée pour la route.The RequestDelegate is used as the route handler when the route matches. D’autres méthodes de cette famille permettent de configurer un pipeline de middleware utilisé comme gestionnaire de routage.Other methods in this family allow configuring a middleware pipeline for use as the route handler. Si la méthode Map* n’accepte pas de gestionnaire, comme MapRoute, elle utilise le DefaultHandler.If the Map* method doesn't accept a handler, such as MapRoute, it uses the DefaultHandler.

Les méthodes Map[Verb] utilisent des contraintes pour limiter la route au verbe HTTP dans le nom de la méthode.The Map[Verb] methods use constraints to limit the route to the HTTP Verb in the method name. Par exemple, consultez MapGet et MapVerb.For example, see MapGet and MapVerb.

Informations de référence sur les modèles de routageRoute template reference

Les jetons placés entre accolades ({ ... }) définissent des paramètres de routage qui sont liés si une correspondance est trouvée pour la route.Tokens within curly braces ({ ... }) define route parameters that are bound if the route is matched. Vous pouvez définir plusieurs paramètres de routage dans un segment de route, mais ils doivent être séparés par une valeur littérale.You can define more than one route parameter in a route segment, but they must be separated by a literal value. Par exemple {controller=Home}{action=Index} n’est pas une route valide, car il n’y a aucune valeur littérale entre {controller} et {action}.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Ces paramètres de routage doivent avoir un nom, et ils autorisent la spécification d’attributs supplémentaires.These route parameters must have a name and may have additional attributes specified.

Un texte littéral autre que les paramètres de routage (par exemple, {id}) et le séparateur de chemin / doit correspondre au texte présent dans l’URL.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. La correspondance de texte ne respecte pas la casse et est basée sur la représentation décodée du chemin des URL.Text matching is case-insensitive and based on the decoded representation of the URLs path. Pour mettre en correspondance un délimiteur de paramètre de route littéral ({ ou }), placez-le dans une séquence d’échappement en répétant le caractère ({{ ou }}).To match a literal route parameter delimiter ({ or }), escape the delimiter by repeating the character ({{ or }}).

Les modèles d’URL qui tentent de capturer un nom de fichier avec une extension de fichier facultative doivent faire l’objet de considérations supplémentaires.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Prenez par exemple le modèle files/{filename}.{ext?}.For example, consider the template files/{filename}.{ext?}. Quand des valeurs existent à la fois pour filename et pour ext, les deux valeurs sont renseignées.When values for both filename and ext exist, both values are populated. Si seule une valeur existe pour filename dans l’URL, une correspondance est trouvée pour la route, car le point final (.) est facultatif.If only a value for filename exists in the URL, the route matches because the trailing period (.) is optional. Les URL suivantes correspondent à cette route :The following URLs match this route:

  • /files/myFile.txt
  • /files/myFile

Vous pouvez utiliser l’astérisque (*) comme préfixe d’un paramètre de route à lier au reste de l’URI.You can use the asterisk (*) as a prefix to a route parameter to bind to the rest of the URI. Cela s’appelle un paramètre fourre-tout.This is called a catch-all parameter. Par exemple, blog/{*slug} établit une correspondance avec n’importe quel URI commençant par /blog et suivi de n’importe quelle valeur, qui est affectée à la valeur de route slug.For example, blog/{*slug} matches any URI that starts with /blog and has any value following it, which is assigned to the slug route value. Les paramètres fourre-tout peuvent également établir une correspondance avec la chaîne vide.Catch-all parameters can also match the empty string.

Le paramètre fourre-tout place les caractères appropriés dans une séquence d’échappement lorsque la route est utilisée pour générer une URL, y compris les caractères de séparation de chemin (/).The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. Par exemple, la route foo/{*path} avec les valeurs de route { path = "my/path" } génère foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Notez la barre oblique d’échappement.Note the escaped forward slash.

Les paramètres de route peuvent avoir des valeurs par défaut, désignées en spécifiant la valeur par défaut après le nom du paramètre, séparée par un signe égal (=).Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Par exemple, {controller=Home} définit Home comme valeur par défaut de controller.For example, {controller=Home} defines Home as the default value for controller. La valeur par défaut est utilisée si aucune valeur n’est présente dans l’URL pour le paramètre.The default value is used if no value is present in the URL for the parameter. Vous pouvez rendre facultatifs les paramètres de route en ajoutant un point d’interrogation (?) à la fin du nom du paramètre, comme dans id?.Route parameters are made optional by appending a question mark (?) to the end of the parameter name, as in id?. La différence entre les valeurs facultatives et les paramètres de route par défaut est qu’un paramètre de route ayant une valeur par défaut produit toujours une valeur, tandis qu’un paramètre facultatif a une valeur seulement quand celle-ci est fournie par l’URL de requête.The difference between optional values and default route parameters is that a route parameter with a default value always produces a value—an optional parameter has a value only when a value is provided by the request URL.

Les paramètres de route peuvent avoir des contraintes, qui doivent correspondre à la valeur de route liée à partir de l’URL.Route parameters may have constraints that must match the route value bound from the URL. L’ajout d’un signe deux-points (:) et d’un nom de contrainte après le nom du paramètre de routage spécifie une contrainte inline sur un paramètre de routage.Adding a colon (:) and constraint name after the route parameter name specifies an inline constraint on a route parameter. Si la contrainte nécessite des arguments, ils sont fournis entre parenthèses ((...)) après le nom de la contrainte.If the constraint requires arguments, they're enclosed in parentheses ((...)) after the constraint name. Il est possible de spécifier plusieurs contraintes inline en ajoutant un autre signe deux-points (:) et le nom d’une autre contrainte.Multiple inline constraints can be specified by appending another colon (:) and constraint name.

Le nom de la contrainte et les arguments sont passés au service IInlineConstraintResolver pour créer une instance de IRouteConstraint à utiliser dans le traitement des URL.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. Par exemple, le modèle de routage blog/{article:minlength(10)} spécifie une contrainte minlength avec l’argument 10.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Pour plus d’informations sur les contraintes de route et pour obtenir la liste des contraintes fournies par le framework, consultez la section Informations de référence sur les contraintes de route.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Le tableau suivant montre des exemples de modèles de route et leur comportement.The following table demonstrates example route templates and their behavior.

Modèle de routageRoute Template Exemple d’URI en correspondanceExample Matching URI URI de la requête…The request URI…
hello /hello Correspond seulement au chemin unique /hello.Only matches the single path /hello.
{Page=Home} / Correspond à Page et le définit sur Home.Matches and sets Page to Home.
{Page=Home} /Contact Correspond à Page et le définit sur Contact.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Mappe au contrôleur Products et à l’action List.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Mappe au contrôleur Products et à l’action Details (id défini sur 123).Maps to the Products controller and Details action (id set to 123).
{controller=Home}/{action=Index}/{id?} / Mappe au contrôleur Home et à la méthode Index (id est ignoré).Maps to the Home controller and Index method (id is ignored).

L’utilisation d’un modèle est généralement l’approche la plus simple pour le routage.Using a template is generally the simplest approach to routing. Il est également possible de spécifier des contraintes et des valeurs par défaut hors du modèle de routage.Constraints and defaults can also be specified outside the route template.

Conseil

Activez la journalisation pour voir comment les implémentations de routage intégrées, comme Route, établissent des correspondances avec les requêtes.Enable Logging to see how the built-in routing implementations, such as Route, match requests.

Informations de référence sur les contraintes de routageRoute constraint reference

Les contraintes de route s’exécutent quand une correspondance s’est produite pour l’URL entrante, et le chemin de l’URL est tokenisé en valeurs de route.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. En général, les contraintes de routage inspectent la valeur de route associée par le biais du modèle de routage, et créent une décision oui/non indiquant si la valeur est, ou non, acceptable.Route constraints generally inspect the route value associated via the route template and make a yes/no decision about whether or not the value is acceptable. Certaines contraintes de routage utilisent des données hors de la valeur de route pour déterminer si la requête peut être routée.Some route constraints use data outside the route value to consider whether the request can be routed. Par exemple, HttpMethodRouteConstraint peut accepter ou rejeter une requête en fonction de son verbe HTTP.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Les contraintes sont utilisées dans le routage des requêtes et la génération des liens.Constraints are used in routing requests and link generation.

Avertissement

N’utilisez pas de contraintes pour la validation des entrées.Don't use constraints for input validation. Si des contraintes sont utilisées pour la validation des entrées, une entrée non valide génère une réponse 404 - Introuvable au lieu d’une réponse 400 - Requête incorrecte avec un message d’erreur approprié.If constraints are used for input validation, invalid input results in a 404 - Not Found response instead of a 400 - Bad Request with an appropriate error message. Les contraintes de route sont utilisées pour lever l’ambiguïté entre des routes similaires, et non pas pour valider les entrées d’une route particulière.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

Le tableau suivant montre des exemples de contrainte de route et leur comportement attendu.The following table demonstrates example route constraints and their expected behavior.

contrainteconstraint  ExempleExample Exemples de correspondancesExample Matches NotesNotes
int {id:int} 123456789, -123456789123456789, -123456789 Correspond à n’importe quel entierMatches any integer
bool {active:bool} true, FALSEtrue, FALSE Correspond à true ou à false (non-respect de la casse)Matches true or false (case-insensitive)
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Correspond à une DateTime valeur valide dans la culture dite indifférente.Matches a valid DateTime value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Correspond à une decimal valeur valide dans la culture dite indifférente.Matches a valid decimal value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une double valeur valide dans la culture dite indifférente.Matches a valid double value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Correspond à une float valeur valide dans la culture dite indifférente.Matches a valid float value in the invariant culture. Consultez l’avertissement précédent.See preceding warning.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638}CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Correspond à une valeur Guid valideMatches a valid Guid value
long {ticks:long} 123456789, -123456789123456789, -123456789 Correspond à une valeur long valideMatches a valid long value
minlength(value) {username:minlength(4)} Rick La chaîne doit comporter au moins 4 caractèresString must be at least 4 characters
maxlength(value) {filename:maxlength(8)} Richard La chaîne ne doit pas comporter plus de 8 caractèresString must be no more than 8 characters
length(length) {filename:length(12)} somefile.txt La chaîne doit comporter exactement 12 caractèresString must be exactly 12 characters long
length(min,max) {filename:length(8,16)} somefile.txt La chaîne doit comporter au moins 8 caractères et pas plus de 16 caractèresString must be at least 8 and no more than 16 characters long
min(value) {age:min(18)} 19 La valeur entière doit être au moins égale à 18Integer value must be at least 18
max(value) {age:max(120)} 91 La valeur entière ne doit pas être supérieure à 120Integer value must be no more than 120
range(min,max) {age:range(18,120)} 91 La valeur entière doit être au moins égale à 18 mais ne doit pas être supérieure à 120Integer value must be at least 18 but no more than 120
alpha {name:alpha} Rick La chaîne doit se composer d’un ou de plusieurs caractères alphabétiques (a-z, non-respect de la casse)String must consist of one or more alphabetical characters (a-z, case-insensitive)
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 La chaîne doit correspondre à l’expression régulière (voir les conseils relatifs à la définition d’une expression régulière)String must match the regular expression (see tips about defining a regular expression)
required {name:required} Rick Utilisé pour garantir qu’une valeur autre qu’un paramètre est présente pendant la génération de l’URLUsed to enforce that a non-parameter value is present during URL generation

Il est possible d’appliquer plusieurs contraintes séparées par un point-virgule à un même paramètre.Multiple, colon-delimited constraints can be applied to a single parameter. Par exemple, la contrainte suivante limite un paramètre à une valeur entière supérieure ou égale à 1 :For example, the following constraint restricts a parameter to an integer value of 1 or greater:

[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

Avertissement

Les contraintes de routage qui vérifient que l’URL peut être convertie en type CLR (comme int ou DateTime) utilisent toujours la culture invariant.Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. ces contraintes partent du principe que l’URL n’est pas localisable.These constraints assume that the URL is non-localizable. Les contraintes de routage fournies par le framework ne modifient pas les valeurs stockées dans les valeurs de route.The framework-provided route constraints don't modify the values stored in route values. Toutes les valeurs de route analysées à partir de l’URL sont stockées sous forme de chaînes.All route values parsed from the URL are stored as strings. Par exemple, la contrainte float tente de convertir la valeur de route en valeur float, mais la valeur convertie est utilisée uniquement pour vérifier qu’elle peut être convertie en valeur float.For example, the float constraint attempts to convert the route value to a float, but the converted value is used only to verify it can be converted to a float.

Expressions régulièresRegular expressions

Le framework ASP.NET Core ajoute RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant au constructeur d’expression régulière.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Pour obtenir une description de ces membres, consultez RegexOptions.See RegexOptions for a description of these members.

Les expressions régulières utilisent les délimiteurs et des jetons semblables à ceux utilisés par le service de routage et le langage C#.Regular expressions use delimiters and tokens similar to those used by Routing and the C# language. Les jetons d’expression régulière doivent être placés dans une séquence d’échappement.Regular expression tokens must be escaped. Pour que l’expression régulière ^\d{3}-\d{2}-\d{4}$ puisse être utilisée dans le routage, il faut que les caractères \ (une seule barre oblique inverse) soit fournis dans la chaîne sous la forme \\ (double barre oblique inverse) dans le fichier source C#, pour placer en échappement le caractère d’échappement de chaîne \ (sauf en cas d’utilisation de littéraux de chaîne textuelle).To use the regular expression ^\d{3}-\d{2}-\d{4}$ in routing, the expression must have the \ (single backslash) characters provided in the string as \\ (double backslash) characters in the C# source file in order to escape the \ string escape character (unless using verbatim string literals). Pour placer en échappement les caractères de délimiteur de paramètre de route ({, }, [, ]), doublez les caractères dans l’expression ({{, }, [[, ]]).To escape routing parameter delimiter characters ({, }, [, ]), double the characters in the expression ({{, }, [[, ]]). Le tableau suivant montre une expression régulière et la version placée en échappement.The following table shows a regular expression and the escaped version.

Expression régulièreRegular Expression Expression régulière en échappementEscaped Regular Expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Les expressions régulières utilisées dans le routage commencent souvent par un caret (^) et correspondent à la position de début de la chaîne.Regular expressions used in routing often start with the caret (^) character and match starting position of the string. Les expressions se terminent souvent par le signe dollar ($) de caractère et correspondent à la fin de la chaîne.The expressions often end with the dollar sign ($) character and match end of the string. Les caractères ^ et $ garantissent que l’expression régulière établit une correspondance avec la totalité de la valeur du paramètre de route.The ^ and $ characters ensure that the regular expression match the entire route parameter value. Sans les caractères ^ et $, l’expression régulière peut correspondre à n’importe quelle sous-chaîne dans la chaîne, ce qui est souvent indésirable.Without the ^ and $ characters, the regular expression match any substring within the string, which is often undesirable. Le tableau suivant contient des exemples et explique pourquoi ils établissent ou non une correspondance.The following table provides examples and explains why they match or fail to match.

ExpressionExpression StringString CorrespondMatch CommentaireComment
[a-z]{2} hellohello OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} 123abc456123abc456 OuiYes Correspondances de sous-chaînesSubstring matches
[a-z]{2} mzmz OuiYes Correspondance avec l’expressionMatches expression
[a-z]{2} MZMZ OuiYes Non-respect de la casseNot case sensitive
^[a-z]{2}$ hellohello NonNo Voir ^ et $ ci-dessusSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NonNo Voir ^ et $ ci-dessusSee ^ and $ above

Pour plus d’informations sur la syntaxe des expressions régulières, consultez Expressions régulières du .NET Framework.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Pour contraindre un paramètre à un ensemble connu de valeurs possibles, utilisez une expression régulière.To constrain a parameter to a known set of possible values, use a regular expression. Par exemple, {action:regex(^(list|get|create)$)} établit une correspondance avec la valeur de route action uniquement pour list, get ou create.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Si elle est passée dans le dictionnaire de contraintes, la chaîne ^(list|get|create)$ est équivalente.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Les contraintes passées dans le dictionnaire de contraintes (c’est-à-dire qui ne sont pas inline dans un modèle) qui ne correspondent pas à l’une des contraintes connues sont également traitées comme des expressions régulières.Constraints that are passed in the constraints dictionary (not inline within a template) that don't match one of the known constraints are also treated as regular expressions.

Contraintes d’itinéraire personnaliséCustom Route Constraints

Outre les contraintes d’itinéraire intégré, les contraintes d’itinéraire personnalisé peuvent être créées en implémentant l’interface IRouteConstraint.In addition to the built-in route constraints, custom route constraints can be created by implementing the IRouteConstraint interface. L’interface IRouteConstraint contient une méthode unique, Match, qui retourne true si la contrainte est satisfaite et false dans le cas contraire.The IRouteConstraint interface contains a single method, Match, which returns true if the constraint is satisfied and false otherwise.

Pour utiliser un IRouteConstraint personnalisé, le type de contrainte d’itinéraire doit être inscrit avec le ConstraintMap de l’application dans le conteneur de service de l’application.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the app's service container. Un ConstraintMap est un dictionnaire qui mappe les clés de contrainte d’itinéraire aux implémentations IRouteConstraint qui valident ces contraintes.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Le ConstraintMap d’une application peut être mis à jour dans Startup.ConfigureServices dans le cadre d’un appel services.AddRouting ou en configurant RouteOptions directement avec services.Configure<RouteOptions>.An app's ConstraintMap can be updated in Startup.ConfigureServices either as part of a services.AddRouting call or by configuring RouteOptions directly with services.Configure<RouteOptions>. Par exemple :For example:

services.AddRouting(options =>
{
    options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
});

La contrainte peut ensuite être appliquée aux itinéraires de la manière habituelle, en utilisant le nom spécifié lors de l’inscription du type de contrainte.The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. Par exemple :For example:

[HttpGet("{id:customName}")]
public ActionResult<string> Get(string id)

Informations de référence sur la génération d’URLURL generation reference

L’exemple suivant montre comment générer un lien vers une route selon un dictionnaire de valeurs de route et un RouteCollection données.The following example shows how to generate a link to a route given a dictionary of route values and a RouteCollection.

app.Run(async (context) =>
{
    var dictionary = new RouteValueDictionary
    {
        { "operation", "create" },
        { "id", 123}
    };

    var vpc = new VirtualPathContext(context, null, dictionary, 
        "Track Package Route");
    var path = routes.GetVirtualPath(vpc).VirtualPath;

    context.Response.ContentType = "text/html";
    await context.Response.WriteAsync("Menu<hr/>");
    await context.Response.WriteAsync(
        $"<a href='{path}'>Create Package 123</a><br/>");
});

Le VirtualPath généré à la fin de l’exemple précédent est /package/create/123.The VirtualPath generated at the end of the preceding sample is /package/create/123. Le dictionnaire fournit les valeurs de route operation et id du modèle « Suivi de package de route », package/{operation}/{id}.The dictionary supplies the operation and id route values of the "Track Package Route" template, package/{operation}/{id}. Pour plus d’informations, consultez l’exemple de code dans la section Utilisation du middleware de routage ou l’exemple d’application.For details, see the sample code in the Use Routing Middleware section or the sample app.

Le deuxième paramètre pour le constructeur VirtualPathContext est une collection de valeurs ambiantes.The second parameter to the VirtualPathContext constructor is a collection of ambient values. Les valeurs ambiantes sont pratiques à utiliser, car elles limitent le nombre de valeurs qu’un développeur doit spécifier dans un contexte de requête.Ambient values are convenient to use because they limit the number of values a developer must specify within a request context. Les valeurs de route actuelles de la requête actuelle sont considérées comme des valeurs ambiantes pour la génération de liens.The current route values of the current request are considered ambient values for link generation. Dans l’action About de HomeController d’une application ASP.NET Core MVC, vous n’avez pas besoin de spécifier la valeur de route du contrôleur pour créer un lien vers l’action Index : la valeur ambiante de Home est utilisée.In an ASP.NET Core MVC app's About action of the HomeController, you don't need to specify the controller route value to link to the Index action—the ambient value of Home is used.

Les valeurs ambiantes qui ne correspondent pas à un paramètre sont ignorées.Ambient values that don't match a parameter are ignored. Les valeurs ambiantes sont également ignorées quand une valeur explicitement fournie remplace la valeur ambiante.Ambient values are also ignored when an explicitly provided value overrides the ambient value. La mise en correspondance se produit de gauche à droite dans l’URL.Matching occurs from left to right in the URL.

Les valeurs fournies explicitement mais qui n’ont pas de correspondance avec un segment de la route sont ajoutées à la chaîne de requête.Values explicitly provided but that don't match a segment of the route are added to the query string. Le tableau suivant présente le résultat en cas d’utilisation du modèle de routage {controller}/{action}/{id?}.The following table shows the result when using the route template {controller}/{action}/{id?}.

Valeurs ambiantesAmbient Values Valeurs explicitesExplicit Values RésultatResult
controller = "Home"controller = "Home" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" controller = "Order", action = "About"controller = "Order", action = "About" /Order/About
controller = "Home", color = "Red"controller = "Home", color = "Red" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" action = "About", color = "Red"action = "About", color = "Red" /Home/About?color=Red

Si une route a une valeur par défaut qui ne correspond pas à un paramètre et que cette valeur est explicitement fournie, elle doit correspondre à la valeur par défaut :If a route has a default value that doesn't correspond to a parameter and that value is explicitly provided, it must match the default value:

routes.MapRoute("blog_route", "blog/{*slug}",
    defaults: new { controller = "Blog", action = "ReadPost" });

La génération de liens génère un lien pour cette route seulement quand les valeurs correspondantes pour controller et pour action sont fournies.Link generation only generates a link for this route when the matching values for controller and action are provided.

Segments complexesComplex segments

Les segments complexes (par exemple, [Route("/x{token}y")]) sont traités par la mise en correspondance des littéraux de droite à gauche de manière non gourmande.Complex segments (for example [Route("/x{token}y")]) are processed by matching up literals from right to left in a non-greedy way. Consultez ce code pour obtenir une explication détaillée de la façon dont les segments complexes sont mis en correspondance.See this code for a detailed explanation of how complex segments are matched. L’exemple de code n’est pas utilisé par ASP.NET Core, mais il fournit une bonne explication des segments complexes.The code sample is not used by ASP.NET Core, but it provides a good explanation of complex segments.