Routing in ASP.NET CoreRouting in ASP.NET Core

Von Ryan Nowak, Kirk Larkin und Rick AndersonBy Ryan Nowak, Kirk Larkin, and Rick Anderson

Das Routing wird für das Abgleichen von HTTP-Anforderungen und das Verteilen an ausführbare Endpunkte der App eingesetzt.Routing is responsible for matching incoming HTTP requests and dispatching those requests to the app's executable endpoints. Endpunkte sind die Einheiten des ausführbaren Codes für die Anforderungsverarbeitung in der App.Endpoints are the app's units of executable request-handling code. Endpunkte werden in der App definiert und beim Start der App konfiguriert.Endpoints are defined in the app and configured when the app starts. Beim Endpunktabgleich können Werte aus der Anforderungs-URL extrahiert und für die Verarbeitung der Anforderung bereitgestellt werden.The endpoint matching process can extract values from the request's URL and provide those values for request processing. Mithilfe von Endpunktinformationen aus der App lassen sich durch das Routing URLs generieren, die Endpunkten zugeordnet werden.Using endpoint information from the app, routing is also able to generate URLs that map to endpoints.

Apps können das Routing mit folgenden Funktionen konfigurieren:Apps can configure routing using:

  • ControllerControllers
  • Razor PagesRazor Pages
  • SignalR
  • gRPC-DienstegRPC Services
  • Endpunktfähige Middleware wie IntegritätsprüfungenEndpoint-enabled middleware such as Health Checks.
  • Für das Routing registrierte Delegate und LambdasDelegates and lambdas registered with routing.

In diesem Artikel werden die grundlegenden Details zum ASP.NET Core-Routing beschrieben.This document covers low-level details of ASP.NET Core routing. Informationen zur Routingkonfiguration finden Sie wie folgt:For information on configuring routing:

Das in diesem Dokument beschriebene Endpunktroutingsystem gilt für ASP.NET Core 3.0 und höher.The endpoint routing system described in this document applies to ASP.NET Core 3.0 and later. Weitere Informationen zum vorherigen Routingsystem, das auf IRouter basiert, erhalten Sie, wenn Sie die ASP.NET Core 2.1-Version wie folgt auswählen:For information on the previous routing system based on IRouter, select the ASP.NET Core 2.1 version using one of the following approaches:

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

Die Downloadbeispiele für dieses Dokument werden durch eine bestimmte Startup-Klasse aktiviert.The download samples for this document are enabled by a specific Startup class. Um ein bestimmtes Beispiel auszuführen, ändern Sie Program.cs, um die gewünschte Startup-Klasse aufzurufen.To run a specific sample, modify Program.cs to call the desired Startup class.

RoutinggrundlagenRouting basics

Alle ASP.NET Core-Vorlagen enthalten die Routingfunktionen im generierten Code.All ASP.NET Core templates include routing in the generated code. Das Routing wird in Startup.Configure in der Middlewarepipeline registriert.Routing is registered in the middleware pipeline in Startup.Configure.

Der folgende Code veranschaulicht ein einfaches Beispiel für das Routing: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!");
        });
    });
}

Beim Routing wird ein Middlewarepaar verwendet, das durch UseRouting und UseEndpoints registriert wird:Routing uses a pair of middleware, registered by UseRouting and UseEndpoints:

  • UseRouting fügt der Middlewarepipeline einen Routenabgleich hinzu.UseRouting adds route matching to the middleware pipeline. Diese Middleware prüft die in der App definierten Endpunkte und wählt anhand der Anforderung die beste Übereinstimmung aus.This middleware looks at the set of endpoints defined in the app, and selects the best match based on the request.
  • UseEndpoints fügt der Middlewarepipeline die Endpunktausführung hinzu.UseEndpoints adds endpoint execution to the middleware pipeline. Dabei wird der mit dem ausgewählten Endpunkt verknüpfte Delegat ausgeführt.It runs the delegate associated with the selected endpoint.

Das vorherige Beispiel enthält eine einzelnen Route-zu- Code-Endpunkt unter Verwendung der MapGet-Methode:The preceding example includes a single route to code endpoint using the MapGet method:

  • Wenn eine GET-HTTP-Anforderung an die Stamm-URL /gesendet wird:When an HTTP GET request is sent to the root URL /:
    • Der angezeigte Anforderungsdelegat wird ausgeführt.The request delegate shown executes.
    • Hello World! wird in die HTTP-Antwort geschrieben.Hello World! is written to the HTTP response. Die Stamm-URL / lautet standardmäßig https://localhost:5001/.By default, the root URL / is https://localhost:5001/.
  • Wenn die Anforderungsmethode nicht GET bzw. die Stamm-URL nicht / ist, gibt es keinen Routenabgleich und es wird ein HTTP-404-Fehler zurückgegeben.If the request method is not GET or the root URL is not /, no route matches and an HTTP 404 is returned.

EndpunktEndpoint

Die MapGet-Methode wird verwendet, um einen Endpunkt zu definieren.The MapGet method is used to define an endpoint. Ein Endpunkt kann Folgendes sein:An endpoint is something that can be:

  • Ausgewählt, indem die URL und die HTTP-Methode abgeglichen werden.Selected, by matching the URL and HTTP method.
  • Ausgeführt, indem ein Delegat ausgeführt wird.Executed, by running the delegate.

Endpunkte, die von der App zugeordnet und ausgeführt werden können, sind in UseEndpoints konfiguriert.Endpoints that can be matched and executed by the app are configured in UseEndpoints. Mit MapGet, MapPost und ähnlichen Methoden werden beispielsweise Anforderungsdelegate mit dem Routingsystem verbunden.For example, MapGet, MapPost, and similar methods connect request delegates to the routing system. Zudem können weitere Methoden zur Verbindung von ASP.NET Core-Frameworkfunktionen mit dem Routingsystem verwendet werden:Additional methods can be used to connect ASP.NET Core framework features to the routing system:

Das folgende Beispiel zeigt das Routing mit einer anspruchsvolleren Routenvorlage: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}!");
    });
});

Die Zeichenfolge /hello/{name:alpha} ist eine Routenvorlage.The string /hello/{name:alpha} is a route template. Sie wird verwendet, um zu konfigurieren, wie der Endpunkt abgeglichen wird.It is used to configure how the endpoint is matched. In diesem Fall gleicht die Vorlage Folgendes ab:In this case, the template matches:

  • Eine URL wie /hello/RyanA URL like /hello/Ryan
  • Alle URL-Pfade, die mit /hello/ beginnen, gefolgt von einer Sequenz alphabetischer Zeichen.Any URL path that begins with /hello/ followed by a sequence of alphabetic characters. :alpha wendet eine Routeneinschränkung an, die nur alphabetische Zeichen abgleicht.:alpha applies a route constraint that matches only alphabetic characters. Routeneinschränkungen werden weiter unten in diesem Dokument erläutert.Route constraints are explained later in this document.

Das zweite Segment des URL-Pfads, {name:alpha}:The second segment of the URL path, {name:alpha}:

Das in diesem Dokument beschriebene Endpunktroutingsystem gilt ab ASP.NET Core 3.0.The endpoint routing system described in this document is new as of ASP.NET Core 3.0. Alle Versionen von ASP.NET Core unterstützen jedoch dieselben Routenvorlagenfunktionen und Routeneinschränkungen.However, all versions of ASP.NET Core support the same set of route template features and route constraints.

Das folgende Beispiel zeigt das Routing mit Integritätsprüfungen und Autorisierung: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!");
        });
    });
}

Wenn Sie möchten, dass Codekommentare in anderen Sprachen als Englisch angezeigt werden, informieren Sie uns in diesem GitHub-Issue.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

Im vorherigen Beispiel wird veranschaulicht, wie Sie:The preceding example demonstrates how:

  • Die Autorisierungsmiddleware für das Routing verwenden.The authorization middleware can be used with routing.
  • Endpunkte zum Konfigurieren des Autorisierungsverhaltens verwendet werden können.Endpoints can be used to configure authorization behavior.

Der MapHealthChecks-Aufruf fügt einen Endpunkt für eine Integritätsprüfung hinzu.The MapHealthChecks call adds a health check endpoint. Durch die Verkettung von RequireAuthorization mit diesem Aufruf wird eine Autorisierungsrichtlinie an den Endpunkt angefügt.Chaining RequireAuthorization on to this call attaches an authorization policy to the endpoint.

Der Aufruf von UseAuthentication und UseAuthorization wird die Authentifizierungs- und Autorisierungsmiddleware hinzugefügt.Calling UseAuthentication and UseAuthorization adds the authentication and authorization middleware. Diese Middleware wird zum Ausführen folgender Aktionen zwischen UseRouting und UseEndpoints platziert:These middleware are placed between UseRouting and UseEndpoints so that they can:

  • Anzeigen des von UseRouting ausgewählten Endpunkts.See which endpoint was selected by UseRouting.
  • Anwenden einer Autorisierungsrichtlinie vor dem Senden von UseEndpoints an den Endpunkt.Apply an authorization policy before UseEndpoints dispatches to the endpoint.

EndpunktmetadatenEndpoint metadata

Im vorangehenden Beispiel gibt es zwei Endpunkte, aber nur dem für die Integritätsprüfung ist eine Autorisierungsrichtlinie angefügt.In the preceding example, there are two endpoints, but only the health check endpoint has an authorization policy attached. Wenn die Anforderung mit dem Endpunkt der Integritätsprüfung, /healthz, übereinstimmt, wird eine Autorisierungsprüfung durchgeführt.If the request matches the health check endpoint, /healthz, an authorization check is performed. Dadurch wird veranschaulicht, dass Endpunkten zusätzliche Daten zugeordnet werden können.This demonstrates that endpoints can have extra data attached to them. Diese zusätzlichen Daten werden als Metadaten des Endpunkts bezeichnet:This extra data is called endpoint metadata:

  • Die Metadaten lassen sich von routingfähiger Middleware verarbeiten.The metadata can be processed by routing-aware middleware.
  • Die Metadaten können einen beliebigen .NET-Typ aufweisen.The metadata can be of any .NET type.

RoutingkonzepteRouting concepts

Durch Hinzufügen des effizienten Endpunkt-Konzepts stellt das Routingsystem eine Ergänzung der Middlewarepipeline dar.The routing system builds on top of the middleware pipeline by adding the powerful endpoint concept. Endpunkte stehen für Funktionseinheiten der App, die sich in Bezug auf Routing, Autorisierung und die Anzahl der ASP.NET Core-Systeme voneinander unterscheiden.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.

ASP.NET Core-EndpunktdefinitionASP.NET Core endpoint definition

Ein ASP.NET Core-Endpunkt ist:An ASP.NET Core endpoint is:

Der folgende Code zeigt, wie der Endpunkt, der mit der aktuellen Anforderung übereinstimmt, abgerufen und geprüft werden kann: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!");
        });
    });
}

Der Endpunkt, falls ausgewählt, kann aus dem HttpContext-Element abgerufen werden.The endpoint, if selected, can be retrieved from the HttpContext. Seine Eigenschaften können geprüft werden.Its properties can be inspected. Endpunktobjekte sind unveränderlich und können nach der Erstellung nicht mehr geändert werden.Endpoint objects are immutable and cannot be modified after creation. Der häufigste Typ des Endpunkts ist eine RouteEndpoint-Klasse.The most common type of endpoint is a RouteEndpoint. Die RouteEndpoint-Klasse enthält Informationen, durch die diese vom Routingsystem ausgewählt werden kann.RouteEndpoint includes information that allows it to be to selected by the routing system.

Im vorangehenden Code wird mit app.Use eine Middleware inline konfiguriert.In the preceding code, app.Use configures an in-line middleware.

Der folgende Code zeigt, dass es, je nachdem, wo app.Use in der Pipeline aufgerufen wird, möglicherweise keinen Endpunkt gibt: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);
});

In diesem vorangehenden Beispiel werden Console.WriteLine-Anweisungen hinzugefügt, die anzeigen, ob ein Endpunkt ausgewählt wurde oder nicht.This preceding sample adds Console.WriteLine statements that display whether or not an endpoint has been selected. Aus Gründen der Übersichtlichkeit wird in dem Beispiel dem bereitgestellten /-Endpunkt ein Anzeigename zugewiesen.For clarity, the sample assigns a display name to the provided / endpoint.

Wenn Sie diesen Code mit einer URL / ausführen, wird Folgendes angezeigt:Running this code with a URL of / displays:

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

Wenn Sie diesen Code mit einer anderen URL ausführen, wird Folgendes angezeigt:Running this code with any other URL displays:

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

Diese Ausgabe zeigt Folgendes:This output demonstrates that:

  • Der Endpunkt ist immer NULL, bevor UseRouting aufgerufen wird.The endpoint is always null before UseRouting is called.
  • Wenn eine Übereinstimmung gefunden wird, ist der Endpunkt zwischen UseRouting und UseEndpoints ungleich NULL.If a match is found, the endpoint is non-null between UseRouting and UseEndpoints.
  • Die UseEndpoints-Middleware ist eine Terminalmiddleware, wenn eine Übereinstimmung gefunden wird.The UseEndpoints middleware is terminal when a match is found. Terminalmiddleware wird weiter unten in diesem Dokument definiert.Terminal middleware is defined later in this document.
  • Die Middleware nach UseEndpoints wird nur ausgeführt, wenn keine Übereinstimmung gefunden wird.The middleware after UseEndpoints execute only when no match is found.

Die UseRouting-Middleware verwendet die SetEndpoint-Methode, um den Endpunkt an den aktuellen Kontext anzufügen.The UseRouting middleware uses the SetEndpoint method to attach the endpoint to the current context. Es ist möglich, die UseRouting-Middleware durch benutzerdefinierte Logik zu ersetzen und dennoch die Vorteile durch die Verwendung von Endpunkten zu nutzen.It's possible to replace the UseRouting middleware with custom logic and still get the benefits of using endpoints. Endpunkte befinden sich auf niedriger Ebene, wie Middleware, und sind nicht an die Routingimplementierung gekoppelt.Endpoints are a low-level primitive like middleware, and aren't coupled to the routing implementation. Die meisten Apps müssen UseRouting nicht durch eigene Logik ersetzen.Most apps don't need to replace UseRouting with custom logic.

Die UseEndpoints-Middleware ist so konzipiert, dass Sie zusammen mit der UseRouting-Middleware verwendet werden kann.The UseEndpoints middleware is designed to be used in tandem with the UseRouting middleware. Die Hauptlogik zum Ausführen eines Endpunkts ist nicht kompliziert.The core logic to execute an endpoint isn't complicated. Mit GetEndpoint können Sie einen Endpunkt abrufen und dann dessen RequestDelegate-Eigenschaft aufrufen.Use GetEndpoint to retrieve the endpoint, and then invoke its RequestDelegate property.

Der folgende Code veranschaulicht, wie Middleware das Routing beeinflussen oder darauf reagieren kann: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; }
}

Im vorherigen Beispiel werden zwei wichtige Konzepte dargestellt:The preceding example demonstrates two important concepts:

  • Die Middleware kann vor UseRouting ausgeführt werden, um die Daten zu ändern, auf denen das Routing basiert.Middleware can run before UseRouting to modify the data that routing operates upon.
  • Die Middleware kann zwischen UseRouting und UseEndpoints ausgeführt werden, um die Ergebnisse des Routings vor der Ausführung des Endpunkts zu verarbeiten.Middleware can run between UseRouting and UseEndpoints to process the results of routing before the endpoint is executed.
    • Middleware, die zwischen UseRouting und UseEndpoints ausgeführt wird:Middleware that runs between UseRouting and UseEndpoints:
      • Überprüft in der Regel die Metadaten, um die Endpunkte zu ermitteln.Usually inspects metadata to understand the endpoints.
      • Trifft häufig Sicherheitsentscheidungen, wie UseAuthorization und UseCors.Often makes security decisions, as done by UseAuthorization and UseCors.
    • Durch die Kombination aus Middleware und Metadaten ist es möglich, für jeden einzelnen Endpunkt Richtlinien zu konfigurieren.The combination of middleware and metadata allows configuring policies per-endpoint.

Der vorangehende Code zeigt ein Beispiel für eine benutzerdefinierte Middleware, die entpunktbezogene Richtlinien unterstützt.The preceding code shows an example of a custom middleware that supports per-endpoint policies. Die Middleware schreibt ein Überwachungsprotokoll für den Zugriff auf vertrauliche Daten in der Konsole.The middleware writes an audit log of access to sensitive data to the console. Die Middleware kann so konfiguriert werden, dass ein Endpunkt mit den AuditPolicyAttribute-Metadaten überwacht wird.The middleware can be configured to audit an endpoint with the AuditPolicyAttribute metadata. In diesem Beispiel wird ein Opt-In-Muster veranschaulicht, bei dem nur Endpunkte überwacht werden, die als vertraulich markiert sind.This sample demonstrates an opt-in pattern where only endpoints that are marked as sensitive are audited. Es ist möglich, diese Logik umgekehrt zu definieren, indem beispielsweise alles geprüft wird, was nicht als sicher markiert ist.It's possible to define this logic in reverse, auditing everything that isn't marked as safe, for example. Das Endpunktmetadaten-System ist flexibel.The endpoint metadata system is flexible. Diese Logik lässt sich für jeden Anwendungsfall passend schreiben.This logic could be designed in whatever way suits the use case.

Der vorherige Beispielcode soll die grundlegenden Konzepte von Endpunkten veranschaulichen.The preceding sample code is intended to demonstrate the basic concepts of endpoints. Das Beispiel ist nicht für Produktionsumgebungen vorgesehen.The sample is not intended for production use. Eine vollständigere Version einer Middleware für Überwachungsprotokolle würde Folgendes bieten:A more complete version of an audit log middleware would:

  • Protokollieren in einer Datei oder einer Datenbank.Log to a file or database.
  • Einschließen von Details wie Benutzer, IP-Adresse, Name des vertraulichen Endpunkts usw.Include details such as the user, IP address, name of the sensitive endpoint, and more.

Die Metadaten der Überwachungsrichtlinie AuditPolicyAttribute sind als Attribute definiert, um die Verwendung mit klassenbasierten Frameworks wie Controllern und SignalR zu erleichtern.The audit policy metadata AuditPolicyAttribute is defined as an Attribute for easier use with class-based frameworks such as controllers and SignalR. Bei Verwendung von Route-zu-Code:When using route to code:

  • Metadaten werden an eine Generator-API angefügt.Metadata is attached with a builder API.
  • Klassenbasierte Frameworks enthalten beim Erstellen von Endpunkten alle Attribute der entsprechenden Methode und Klasse.Class-based frameworks include all attributes on the corresponding method and class when creating endpoints.

Die bewährten Methoden für Metadatentypen sind, sie entweder als Schnittstellen oder als Attribute zu definieren.The best practices for metadata types are to define them either as interfaces or attributes. Schnittstellen und Attribute ermöglichen die Wiederverwendung von Code.Interfaces and attributes allow code reuse. Das Metadatensystem ist flexibel und weist keine Einschränkungen auf.The metadata system is flexible and doesn't impose any limitations.

Vergleichen von Terminalmiddleware und RoutingComparing a terminal middleware and routing

Das folgende Codebeispiel zeigt den Unterschied zwischen Middleware und Routing: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!");
        });
    });
}

Beim in Approach 1: gezeigten Stil von Middleware handelt es sich um Terminalmiddleware.The style of middleware shown with Approach 1: is terminal middleware. Sie wird als Terminalmiddleware bezeichnet, da sie einen Abgleich durchgeführt.It's called terminal middleware because it does a matching operation:

  • Der Abgleich im vorangehenden Beispiel ist Path == "/" für die Middleware und Path == "/Movie" für das Routing.The matching operation in the preceding sample is Path == "/" for the middleware and Path == "/Movie" for routing.
  • Bei einem erfolgreichen Abgleich führt sie bestimmte Funktionen aus und kehrt zurück, anstatt die next-Middleware aufzurufen.When a match is successful, it executes some functionality and returns, rather than invoking the next middleware.

Sie wird „Terminal Middleware“ genannt, da sie die Suche beendet, einige Funktionen ausführt und dann zurückkehrt.It's called terminal middleware because it terminates the search, executes some functionality, and then returns.

Vergleichen von Terminalmiddleware und Routing:Comparing a terminal middleware and routing:

  • Beide Ansätze ermöglichen das Beenden der Verarbeitungspipeline:Both approaches allow terminating the processing pipeline:
    • Die Middleware beendet die Pipeline, indem Sie zurückkehrt, anstatt next aufzurufen.Middleware terminates the pipeline by returning rather than invoking next.
    • Endpunkte beenden immer die Verarbeitung.Endpoints are always terminal.
  • Terminalmiddleware ermöglicht die Positionierung der Middleware an einer beliebigen Stelle in der Pipeline:Terminal middleware allows positioning the middleware at an arbitrary place in the pipeline:
  • Mit Terminalmiddleware kann beliebiger Code beendet werden, wenn die Middleware übereinstimmt:Terminal middleware allows arbitrary code to determine when the middleware matches:
    • Ein benutzerdefinierter Routenabgleichscode kann sehr umständlich und schwierig zu schreiben sein.Custom route matching code can be verbose and difficult to write correctly.
    • Das Routing bietet unkomplizierte Lösungen für typische Apps.Routing provides straightforward solutions for typical apps. Die meisten Apps erfordern keinen benutzerdefinierten Routenabgleichscode.Most apps don't require custom route matching code.
  • Endpunkte haben eine Schnittstelle mit Middleware wie UseAuthorization und UseCors.Endpoints interface with middleware such as UseAuthorization and UseCors.
    • Die Verwendung einer Terminalmiddleware mit UseAuthorization oder UseCors erfordert eine manuelle Verknüpfung mit dem Autorisierungssystem.Using a terminal middleware with UseAuthorization or UseCors requires manual interfacing with the authorization system.

Ein Endpunkt definiert beides:An endpoint defines both:

  • Einen Delegaten zum Verarbeiten von Anforderungen.A delegate to process requests.
  • Eine Sammlung beliebiger Metadaten.A collection of arbitrary metadata. Die Metadaten werden zur Implementierung von übergreifenden Belangen verwendet, die auf Richtlinien und der Konfiguration basieren, die den einzelnen Endpunkten angefügt sind.The metadata is used to implement cross-cutting concerns based on policies and configuration attached to each endpoint.

Terminalmiddleware kann sehr nützlich sein, erfordert aber möglicherweise auch:Terminal middleware can be an effective tool, but can require:

  • Einen großen Codierungs- und Testaufwand.A significant amount of coding and testing.
  • Eine manuelle Integration in andere Systeme für die gewünschte Flexibilität.Manual integration with other systems to achieve the desired level of flexibility.

Ziehen Sie daher zunächst die Integration von Routingfunktionen in Betracht, bevor Sie damit beginnen, Terminalmiddleware zu schreiben.Consider integrating with routing before writing a terminal middleware.

Vorhandene Terminalmiddleware, die in Map oder MapWhen integriert ist, kann in der Regel in einen routingfähigen Endpunkt umgewandelt werden.Existing terminal middleware that integrates with Map or MapWhen can usually be turned into a routing aware endpoint. MapHealthChecks zeigt das Muster für eine Routinglösung:MapHealthChecks demonstrates the pattern for router-ware:

  • Schreiben Sie eine Erweiterungsmethode in der IEndpointRouteBuilder-Schnittstelle.Write an extension method on IEndpointRouteBuilder.
  • Erstellen Sie eine geschachtelte Middlewarepipeline mit CreateApplicationBuilder.Create a nested middleware pipeline using CreateApplicationBuilder.
  • Fügen Sie die Middleware an die neue Pipeline an.Attach the middleware to the new pipeline. In diesem Fall UseHealthChecks.In this case, UseHealthChecks.
  • Verwenden Sie Build, um die Middlewarepipeline in einem RequestDelegate-Delegaten zu erstellen.Build the middleware pipeline into a RequestDelegate.
  • Rufen Sie Map auf, und stellen Sie die neue Middlewarepipeline bereit.Call Map and provide the new middleware pipeline.
  • Geben Sie das Generatorobjekt zurück, das von Map aus der Erweiterungsmethode bereitgestellt wurde.Return the builder object provided by Map from the extension method.

Im folgenden Code ist die Verwendung von MapHealthChecks gezeigt: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!");
        });
    });
}

Das vorangehende Beispiel zeigt, warum das Zurückgeben des Generatorobjekts wichtig ist.The preceding sample shows why returning the builder object is important. Wenn das Generatorobjekt zurückgegeben wird, kann der App-Entwickler Richtlinien konfigurieren, z. B. die Autorisierung für den Endpunkt.Returning the builder object allows the app developer to configure policies such as authorization for the endpoint. In diesem Beispiel ist die Middleware für Integritätsprüfungen nicht direkt in das Autorisierungssystem integriert.In this example, the health checks middleware has no direct integration with the authorization system.

Das Metadatensystem wurde als Antwort auf die Probleme erstellt, die von Erweiterbarkeitsautoren mithilfe von Terminalmiddleware aufgetreten sind.The metadata system was created in response to the problems encountered by extensibility authors using terminal middleware. Für jede Middleware ist es problematisch, deren eigene Integration in das Autorisierungssystem umzusetzen.It's problematic for each middleware to implement its own integration with the authorization system.

URL-ZuordnungURL matching

  • Bei diesem Prozess werden eingehende Anforderungen durch Routing mit einem Endpunkt abgeglichen.Is the process by which routing matches an incoming request to an endpoint.
  • Basiert auf Daten im URL-Pfad und den URL-Headern.Is based on data in the URL path and headers.
  • Kann erweitert werden, um beliebige Daten in der Anforderung zu überprüfen.Can be extended to consider any data in the request.

Wenn eine Routingmiddleware ausgeführt wird, legt sie ein Endpoint-Element fest und leitet Werte an eine Anforderungsfunktion in der HttpContext-Klasse der aktuellen Anforderung weiter:When a routing middleware executes, it sets an Endpoint and route values to a request feature on the HttpContext from the current request:

  • Durch Aufrufen von HttpContext.GetEndPoint wird der Endpunkt abgerufen.Calling HttpContext.GetEndpoint gets the endpoint.
  • HttpRequest.RouteValues ruft die Sammlung der Routenwerte ab.HttpRequest.RouteValues gets the collection of route values.

Middleware, die nach der Routingmiddleware ausgeführt wird, kann den Endpunkt erkennen und Maßnahmen ergreifen.Middleware running after the routing middleware can inspect the endpoint and take action. So kann beispielsweise eine Autorisierungsmiddleware die Erfassung der Metadaten des Endpunkts für eine Autorisierungsrichtlinie abfragen.For example, an authorization middleware can interrogate the endpoint's metadata collection for an authorization policy. Nachdem die gesamte Middleware in der Anforderungsverarbeitungspipeline ausgeführt wurde, wird der Delegat des ausgewählten Endpunkts aufgerufen.After all of the middleware in the request processing pipeline is executed, the selected endpoint's delegate is invoked.

Das Routingsystem ist beim Endpunktrouting für alle Weiterleitungsentscheidungen zuständig.The routing system in endpoint routing is responsible for all dispatching decisions. Da die Middleware Richtlinien auf der Grundlage des ausgewählten Endpunkts anwendet, ist Folgendes wichtig:Because the middleware applies policies based on the selected endpoint, it's important that:

  • Alle Entscheidungen, die sich auf die Verteilung oder die Anwendung von Sicherheitsrichtlinien auswirken können, werden im Routingsystem getroffen.Any decision that can affect dispatching or the application of security policies is made inside the routing system.

Warnung

Wenn für Abwärtskompatibilität ein Controller- oder Razor Pages-Endpunktdelegat ausgeführt wird, werden die Eigenschaften von RouteContext.RouteData auf Grundlage der bisher verarbeiteten Anforderungen auf entsprechende Werte festgelegt.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.

Der Typ RouteContext wird in einer zukünftigen Version als veraltet markiert:The RouteContext type will be marked obsolete in a future release:

  • Migrieren Sie RouteData.Values zu HttpRequest.RouteValues.Migrate RouteData.Values to HttpRequest.RouteValues.
  • Migrieren Sie RouteData.DataTokens, um IDataTokensMetadata aus den Endpunktmetadaten abzurufen.Migrate RouteData.DataTokens to retrieve IDataTokensMetadata from the endpoint metadata.

Der URL-Abgleich erfolgt in mehreren Phasen und kann konfiguriert werden.URL matching operates in a configurable set of phases. In jeder Phase werden mehrere Übereinstimmungen ausgegeben.In each phase, the output is a set of matches. Diese Übereinstimmungen lassen sich in der nächsten Phase weiter eingrenzen.The set of matches can be narrowed down further by the next phase. Die Routingimplementierung garantiert keine Verarbeitungsreihenfolge für übereinstimmende Endpunkte.The routing implementation does not guarantee a processing order for matching endpoints. Alle möglichen Übereinstimmungen werden gleichzeitig verarbeitet.All possible matches are processed at once. Für die URL-Abgleichsphasen gilt folgende Reihenfolge.The URL matching phases occur in the following order. ASP.NET Core:ASP.NET Core:

  1. Verarbeitet den URL-Pfad mit mehreren Endpunkten und ihren Routenvorlagen und sammelt alle Übereinstimmungen.Processes the URL path against the set of endpoints and their route templates, collecting all of the matches.
  2. Nimmt die vorangehende Liste und entfernt die Übereinstimmungen, die nicht zu den angewendeten Routeneinschränkungen passen.Takes the preceding list and removes matches that fail with route constraints applied.
  3. Nimmt die vorangehende Liste und entfernt die Übereinstimmungen, die nicht zu den MatcherPolicy-Instanzen passen.Takes the preceding list and removes matches that fail the set of MatcherPolicy instances.
  4. Verwendet EndpointSelector, um eine abschließende Entscheidung anhand der vorangehenden Liste zu treffen.Uses the EndpointSelector to make a final decision from the preceding list.

Die Liste der Endpunkte wird entsprechend den folgenden Punkten priorisiert:The list of endpoints is prioritized according to:

Alle übereinstimmenden Endpunkte werden in jeder Phase verarbeitet, bis EndpointSelector erreicht ist.All matching endpoints are processed in each phase until the EndpointSelector is reached. EndpointSelector stellt die abschließende Phase dar.The EndpointSelector is the final phase. Darin wird der Endpunkt mit der höchsten Priorität aus den Übereinstimmungen als beste Übereinstimmung ausgewählt.It chooses the highest priority endpoint from the matches as the best match. Wenn es andere Übereinstimmungen mit derselben Priorität wie die beste Übereinstimmung gibt, wird ein Ausnahmefehler wegen einer nicht eindeutigen Übereinstimmung ausgelöst.If there are other matches with the same priority as the best match, an ambiguous match exception is thrown.

Die Routenpriorität wird anhand einer spezifischeren Routenvorlage berechnet, der eine höhere Priorität eingeräumt wird.The route precedence is computed based on a more specific route template being given a higher priority. Dies wird z. B. anhand der Vorlagen /hello und /{message} deutlich:For example, consider the templates /hello and /{message}:

  • Beide stimmen mit dem URL-Pfad /hello überein.Both match the URL path /hello.
  • /hello ist spezifischer und hat daher eine höhere Priorität./hello is more specific and therefore higher priority.

Im Allgemeinen eignet sich die Routenpriorität gut, um die beste Übereinstimmung für die in der Praxis verwendeten URL-Schemata zu finden.In general, route precedence does a good job of choosing the best match for the kinds of URL schemes used in practice. Verwenden Sie Order nur bei Bedarf, um eine Mehrdeutigkeit zu vermeiden.Use Order only when necessary to avoid an ambiguity.

Aufgrund der Erweiterungsmöglichkeiten, die das Routing bietet, kann das Routingsystem die mehrdeutigen Routen nicht im Voraus berechnen.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. Betrachten Sie ein Beispiel wie die Routenvorlagen /{message:alpha} und /{message:int}:Consider an example such as the route templates /{message:alpha} and /{message:int}:

  • Die alpha-Einschränkung gleicht nur alphabetische Zeichen ab.The alpha constraint matches only alphabetic characters.
  • Die int-Einschränkung gleicht nur Zahlen ab.The int constraint matches only numbers.
  • Diese Vorlagen haben die gleiche Routenpriorität, aber es gibt keine einzige URL, auf die sie beide zutreffen.These templates have the same route precedence, but there's no single URL they both match.
  • Wenn das Routingsystem beim Starten einen Mehrdeutigkeitsfehler gemeldet hat, würde dieser den gültigen Anwendungsfall blockieren.If the routing system reported an ambiguity error at startup, it would block this valid use case.

Warnung

Die Reihenfolge der Vorgänge in UseEndpoints wirkt sich nicht auf das Routingverhalten aus, mit einer Ausnahme.The order of operations inside UseEndpoints doesn't influence the behavior of routing, with one exception. MapControllerRoute und MapAreaRoute weisen ihren Endpunkten automatisch einen Reihenfolgenwert zu, basierend auf der Reihenfolge, in der sie aufgerufen werden.MapControllerRoute and MapAreaRoute automatically assign an order value to their endpoints based on the order they are invoked. Dadurch wird das Langzeitverhalten von Controllern simuliert, ohne dass das Routingsystem die gleichen Garantien bietet wie ältere Routingimplementierungen.This simulates long-time behavior of controllers without the routing system providing the same guarantees as older routing implementations.

Bei der bisherigen Routingimplementierung war es möglich, eine Routingerweiterung vorzunehmen, die von der Verarbeitungsreihenfolge der Routen abhängt.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. Endpunktrouting in ASP.NET Core 3.0 und höher:Endpoint routing in ASP.NET Core 3.0 and later:

  • Weist kein Konzept für Routen auf.Doesn't have a concept of routes.
  • Bietet keine garantierte Reihenfolge.Doesn't provide ordering guarantees. Alle Endpunkte werden gleichzeitig verarbeitet.All endpoints are processed at once.

Wenn dies bedeutet, dass Sie mit dem Legacy-Routingsystem nicht weiterkommen, öffnen Sie ein GitHub-Problem zur Unterstützung.If this means you're stuck using the legacy routing system, open a GitHub issue for assistance.

Routenvorlagenpriorität und Reihenfolge der EndpunktauswahlRoute template precedence and endpoint selection order

Die Routenvorlagenpriorität ist ein System, bei dem jeder Routenvorlage ein Wert zugewiesen wird, je nachdem, wie spezifisch diese ist.Route template precedence is a system that assigns each route template a value based on how specific it is. Routenvorlagenpriorität:Route template precedence:

  • Verhindert, dass die Reihenfolge der Endpunkte häufig angepasst werden muss.Avoids the need to adjust the order of endpoints in common cases.
  • Versucht, die allgemeinen Erwartungen an das Routingverhalten abzugleichen.Attempts to match the common-sense expectations of routing behavior.

Dies wird z. B. anhand der Vorlagen /Products/List und /Products/{id} deutlich.For example, consider templates /Products/List and /Products/{id}. Es wäre begründet, anzunehmen, dass /Products/List eine bessere Übereinstimmung als /Products/{id} für den URL-Pfad /Products/List ist.It would be reasonable to assume that /Products/List is a better match than /Products/{id} for the URL path /Products/List. Dies funktioniert, weil das Literalsegment /List eine höhere Priorität hat als das Parametersegment /{id}.The works because the literal segment /List is considered to have better precedence than the parameter segment /{id}.

Wie die Priorisierung im Einzelnen funktioniert, ist an die Definition der Routenvorlagen gekoppelt:The details of how precedence works are coupled to how route templates are defined:

  • Vorlagen mit mehr Segmenten sind in der Regel spezifischer.Templates with more segments are considered more specific.
  • Ein Segment mit Literaltext gilt als spezifischer als ein Parametersegment.A segment with literal text is considered more specific than a parameter segment.
  • Ein Parametersegment mit einer Einschränkung gilt als spezifischer als ein Parametersegment ohne Einschränkung.A parameter segment with a constraint is considered more specific than one without.
  • Ein komplexes Segment wird als genauso spezifisch betrachtet wie ein Parametersegment mit einer Einschränkung.A complex segment is considered as specific as a parameter segment with a constraint.
  • Catch-All-Parameter, die am wenigsten spezifisch sind.Catch-all parameters are the least specific. Unter Catch-All in der Referenz zu Routenvorlagen finden Sie wichtige Informationen zu Catch-All-Routen.See catch-all in the Route template reference for important information on catch-all routes.

Einen Verweis auf genaue Werte finden Sie im Quellcode auf GitHub.See the source code on GitHub for a reference of exact values.

Konzepte zur URL-GenerierungURL generation concepts

URL-Generierung:URL generation:

  • Der Prozess, bei dem durch Routing ein URL-Pfad basierend auf mehreren Routenwerten erstellt wird.Is the process by which routing can create a URL path based on a set of route values.
  • Sie ermöglicht eine logische Trennung zwischen den Endpunkten und den URLs, die auf diese zugreifen.Allows for a logical separation between endpoints and the URLs that access them.

Das Endpunktrouting umfasst die API zur Linkgenerierung (LinkGenerator).Endpoint routing includes the LinkGenerator API. LinkGenerator ist ein Singleton-Dienst, der in DI verfügbar ist.LinkGenerator is a singleton service available from DI. Die LinkGenerator-API kann außerhalb des Kontexts einer ausgeführten Anforderung verwendet werden.The LinkGenerator API can be used outside of the context of an executing request. Mvc.IUrlHelper und Szenarios, die von IUrlHelper abhängig sind (z. B. Taghilfsprogramme, HTML-Hilfsprogramme und Aktionsergebnisse), verwenden die LinkGenerator-API, um entsprechende Funktionen bereitzustellen.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.

Die API zur Linkgenerierung wird von Konzepten wie Adressen und Adressschemas unterstützt.The link generator is backed by the concept of an address and address schemes. Sie können mithilfe eines Adressschemas die Endpunkte bestimmen, die bei der Linkgenerierung berücksichtigt werden sollen.An address scheme is a way of determining the endpoints that should be considered for link generation. Beispielsweise werden Routennamen und Routenwerte als Adressschemas implementiert. Diese Szenarios kennen viele Benutzer von Controllern und Razor Pages.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.

Die API zur Linkgenerierung kann Controller und Razor Pages über die folgenden Erweiterungsmethoden miteinander verknüpfen:The link generator can link to controllers and Razor Pages via the following extension methods:

Beim Überladen dieser Methoden werden Argumente akzeptiert, die den HttpContext umfassen.Overloads of these methods accept arguments that include the HttpContext. Diese Methoden sind zwar in funktionaler Hinsicht äquivalent zu Url.Action und Url.Page, bieten aber zusätzliche Flexibilität und Optionen.These methods are functionally equivalent to Url.Action and Url.Page, but offer additional flexibility and options.

Die GetPath*-Methoden sind Url.Action und Url.Page in der Hinsicht ähnlich, dass sie einen URI mit einem absoluten Pfad generieren.The GetPath* methods are most similar to Url.Action and Url.Page, in that they generate a URI containing an absolute path. Die GetUri*-Methoden generieren immer einen absoluten URI mit einem Schema und einem Host.The GetUri* methods always generate an absolute URI containing a scheme and host. Die Methoden, die einen HttpContext akzeptieren, generieren im Kontext der ausgeführten Anforderung einen URI.The methods that accept an HttpContext generate a URI in the context of the executing request. Die Umgebungsroutenwerte, der URL-basierte Pfad, das Schema und der Host von der ausführenden Anforderung werden so lange verwendet, bis sie außer Kraft gesetzt werden.The ambient route values, URL base path, scheme, and host from the executing request are used unless overridden.

LinkGenerator wird mit einer Adresse aufgerufen.LinkGenerator is called with an address. Ein URI wird in zwei Schritten generiert:Generating a URI occurs in two steps:

  1. Eine Adresse wird an eine Liste von Endpunkten gebunden, die der Adresse zugeordnet werden können.An address is bound to a list of endpoints that match the address.
  2. Jedes RoutePattern eines Endpunkts wird bewertet, bis ein Routenmuster gefunden wird, das den angegebenen Werten zugeordnet werden kann.Each endpoint's RoutePattern is evaluated until a route pattern that matches the supplied values is found. Die daraus resultierende Ausgabe wird mit URI-Teilen kombiniert, die für die API zur Linkgenerierung bereitgestellt wird, und zurückgegeben.The resulting output is combined with the other URI parts supplied to the link generator and returned.

Die von LinkGenerator bereitgestellten Methoden unterstützen die Standardfunktionen zur Generierung von Links für jeden beliebigen Adresstypen.The methods provided by LinkGenerator support standard link generation capabilities for any type of address. Am praktischsten ist es, die API zur Linkgenerierung mit Erweiterungsmethoden zu verwenden, die Vorgänge für einen bestimmten Adresstypen ausführen:The most convenient way to use the link generator is through extension methods that perform operations for a specific address type:

ErweiterungsmethodeExtension Method BeschreibungDescription
GetPathByAddress Generiert einen URI mit einem absoluten Pfad, der auf den angegebenen Werten basiert.Generates a URI with an absolute path based on the provided values.
GetUriByAddress Generiert einen absoluten URI, der auf den angegebenen Werten basiert.Generates an absolute URI based on the provided values.

Warnung

Beachten Sie die folgenden Implikationen zum Aufrufen von LinkGenerator-Methoden:Pay attention to the following implications of calling LinkGenerator methods:

  • Verwenden Sie GetUri*-Erweiterungsmethoden in App-Konfigurationen, die den Host-Header von eingehenden Anforderungen nicht überprüfen, mit Bedacht.Use GetUri* extension methods with caution in an app configuration that doesn't validate the Host header of incoming requests. Wenn der Host-Header von eingehenden Anforderungen nicht überprüft wird, können nicht vertrauenswürdige Anforderungseingaben zurück an den Client in URIs einer Ansicht bzw. Seite zurückgesendet werden.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. Es wird empfohlen, dass alle Produktions-Apps ihren Server so konfigurieren, dass der Host-Header auf bekannte gültige Werte überprüft wird.We recommend that all production apps configure their server to validate the Host header against known valid values.

  • Verwenden Sie LinkGenerator in Kombination mit Map oder MapWhen in Middleware mit Bedacht.Use LinkGenerator with caution in middleware in combination with Map or MapWhen. Map* ändert den Basispfad der ausgeführten Anforderung. Dies beeinflusst die Ausgabe der Linkgenerierung.Map* changes the base path of the executing request, which affects the output of link generation. Für alle LinkGenerator-APIs ist die Angabe eines Basispfads zulässig.All of the LinkGenerator APIs allow specifying a base path. Geben Sie einen leeren Basispfad an, um die Auswirkungen von Map* auf die Linkgenerierung rückgängig zu machen.Specify an empty base path to undo the Map* affect on link generation.

MiddlewarebeispielMiddleware example

Im folgenden Beispiel verwendet eine Middleware die LinkGenerator-API, um eine Verknüpfung zu einer Aktionsmethode herzustellen, die Speicherprodukte aufführt.In the following example, a middleware uses the LinkGenerator API to create a link to an action method that lists store products. Sie können für jede beliebige Klasse in einer App die API zur Linkgenerierung verwenden, indem Sie diese in eine Klasse einfügen und GenerateLink aufrufen: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.");
    }
}

Referenz für RoutenvorlagenRoute template reference

Token in {} definieren Routenparameter, die beim Abgleich der Route gebunden werden.Tokens within {} define route parameters that are bound if the route is matched. In einem Routensegment können mehrere Routenparameter definiert werden, müssen aber durch einen Literalwert getrennt werden.More than one route parameter can be defined in a route segment, but route parameters must be separated by a literal value. {controller=Home}{action=Index} ist z.B. keine gültige Route, da sich zwischen {controller} und {action} kein Literalwert befindet.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Routenparameter müssen einen Namen besitzen und können zusätzliche Attribute aufweisen.Route parameters must have a name and may have additional attributes specified.

Eine Literalzeichenfolge, die nicht den Routenparametern entspricht (z.B. {id}), muss zusammen mit dem Pfadtrennzeichen / mit dem URL-Text übereinstimmen.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. Beim Abgleich von Text wird nicht zwischen Groß-/Kleinbuchstaben unterschieden, und die Übereinstimmung basiert auf der decodierten Repräsentation des URL-Pfads.Text matching is case-insensitive and based on the decoded representation of the URL's path. Damit das Trennzeichen ({ oder }) der Routenparameter-Literalzeichenfolge bei einem Abgleich gefunden wird, muss es doppelt vorhanden sein, was einem Escapezeichen entspricht.To match a literal route parameter delimiter { or }, escape the delimiter by repeating the character. Beispielsweise {{ oder }}.For example {{ or }}.

Sternchen * oder Doppelsternchen **:Asterisk * or double asterisk **:

  • Können als Präfix für einen Routenparameter verwendet werden, um eine Bindung zum verbleibenden Teil des URI herzustellen.Can be used as a prefix to a route parameter to bind to the rest of the URI.
  • Werden Catch-All-Parameter genannt.Are called a catch-all parameters. Zum Beispiel blog/{**slug}:For example, blog/{**slug}:
    • Entspricht einem beliebigen URI, der mit /blog beginnt und einem beliebigen Wert folgt.Matches any URI that starts with /blog and has any value following it.
    • Der Wert nach /blog wird dem Slug-Routenwert zugewiesen.The value following /blog is assigned to the slug route value.

Warnung

Ein catch-all-Parameter kann aufgrund eines Fehlers beim Routing nicht ordnungsgemäß mit Routen übereinstimmen.A catch-all parameter may match routes incorrectly due to a bug in routing. Apps, die von diesem Fehler betroffen sind, weisen die folgenden Merkmale auf:Apps impacted by this bug have the following characteristics:

  • Eine catch-all-Route, zum Beispiel {**slug}"A catch-all route, for example, {**slug}"
  • Die catch-all-Route kann nicht mit Anforderungen abgeglichen werden, die abgeglichen werden sollen.The catch-all route fails to match requests it should match.
  • Durch das Entfernen anderer Routen funktioniert die catch-all-Route.Removing other routes makes catch-all route start working.

Weitere Beispiele zu diesem Fehler finden Sie in den GitHub-Issues 18677 und 16579.See GitHub bugs 18677 and 16579 for example cases that hit this bug.

Eine Opt-in-Behebung für diesen Fehler ist im .NET Core 3.1.301 SDK und höher enthalten.An opt-in fix for this bug is contained in .NET Core 3.1.301 SDK and later. Der folgende Code legt einen internen Switch fest, mit dem dieser Fehler behoben wird: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.

Durch Catch-All-Parameter können auch leere Zeichenfolgen gefunden werden.Catch-all parameters can also match the empty string.

Der Catch-All-Parameter schützt die entsprechenden Zeichen (Escaping), wenn die Route verwendet wird, um eine URL, einschließlich Pfadtrennzeichen (/) zu generieren.The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator / characters. Z.B. generiert die Route foo/{*path} mit den Routenwerten { path = "my/path" }``foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Beachten Sie den umgekehrten Schrägstrich mit Escapezeichen.Note the escaped forward slash. Um Trennzeichen für Roundtrips einsetzen zu können, verwenden Sie das Routenparameterpräfix **.To round-trip path separator characters, use the ** route parameter prefix. Die Route foo/{**path} mit { path = "my/path" } generiert foo/my/path.The route foo/{**path} with { path = "my/path" } generates foo/my/path.

Bei einem URL-Muster, durch das ein Dateiname mit einer optionalen Erweiterung erfasst werden soll, sind noch weitere Aspekte zu berücksichtigen.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Dies wird z.B. anhand der Vorlage files/{filename}.{ext?} deutlich.For example, consider the template files/{filename}.{ext?}. Wenn sowohl für filename als auch für ext Werte vorhanden sind, werden beide Werte angegeben.When values for both filename and ext exist, both values are populated. Wenn nur für filename ein Wert in der URL vorhanden ist, wird für die Route eine Übereinstimmung ermittelt, da der nachstehende Punkt (.) optional ist.If only a value for filename exists in the URL, the route matches because the trailing . is optional. Für die folgenden URLs wird eine Übereinstimmung für die Route ermittelt:The following URLs match this route:

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

Routenparameter können über mehrere Standardwerte verfügen, die nach dem Parameternamen angegeben werden und durch ein Gleichheitszeichen (=) voneinander getrennt werden.Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Mit {controller=Home} wird beispielsweise Home als Standardwert für controller definiert.For example, {controller=Home} defines Home as the default value for controller. Der Standardwert wird verwendet, wenn kein Wert in der Parameter-URL vorhanden ist.The default value is used if no value is present in the URL for the parameter. Routenparameter sind optional, wenn am Ende des Parameternamens ein Fragezeichen (?) angefügt wird.Route parameters are made optional by appending a question mark (?) to the end of the parameter name. Beispielsweise id?.For example, id?. Zwischen optionalen Werten und Standardroutenparametern besteht folgender Unterschied:The difference between optional values and default route parameters is:

  • Ein Routenparameter mit einem Standardwert erzeugt immer einen Wert.A route parameter with a default value always produces a value.
  • Ein optionaler Parameter hat nur dann einen Wert, wenn ein Wert von der Anforderungs-URL bereitgestellt wird.An optional parameter has a value only when a value is provided by the request URL.

Routenparameter können Einschränkungen aufweisen, die mit dem gebundenen Routenwert der URL übereinstimmen müssen.Route parameters may have constraints that must match the route value bound from the URL. Eine Inline-Einschränkung für einen Routenparameter geben Sie an, indem Sie hinter dem Namen des Routenparameters einen Doppelpunkt (:) und einen Einschränkungsnamen hinzufügen.Adding : and constraint name after the route parameter name specifies an inline constraint on a route parameter. Wenn für die Einschränkung Argumente erforderlich sind, werden diese nach dem Einschränkungsnamen in Klammern ((...)) eingeschlossen.If the constraint requires arguments, they're enclosed in parentheses (...) after the constraint name. Mehrere Inline-Einschränkungen können festgelegt werden, indem ein weiterer Doppelpunkt (:) und Einschränkungsname hinzugefügt werden.Multiple inline constraints can be specified by appending another : and constraint name.

Der Einschränkungsname und die Argumente werden dem IInlineConstraintResolver-Dienst übergeben, wodurch eine Instanz von IRouteConstraint für die URL-Verarbeitung erstellt werden kann.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. In der Routenvorlage blog/{article:minlength(10)} wird beispielsweise die Einschränkung minlength mit dem Argument 10 festgelegt.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Weitere Informationen zu Routeneinschränkungen und eine Liste der vom Framework bereitgestellten Einschränkungen finden Sie im Abschnitt Referenz zu Routeneinschränkungen.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Routenparameter können darüber hinaus über Parametertransformatoren verfügen.Route parameters may also have parameter transformers. Diese wandeln den Wert eines Parameters beim Generieren von Links um und passen Aktionen und Seiten an URLs an.Parameter transformers transform a parameter's value when generating links and matching actions and pages to URLs. Wie Einschränkungen können auch Parametertransformatoren einem Routenparameter inline hinzugefügt werden, indem ein Doppelpunkt (:) und der Name des Transformators hinter dem Namen des Routenparameters hinzugefügt werden.Like constraints, parameter transformers can be added inline to a route parameter by adding a : and transformer name after the route parameter name. In der Routenvorlage blog/{article:slugify} wird beispielsweise der Transformator slugify festgelegt.For example, the route template blog/{article:slugify} specifies a slugify transformer. Weitere Informationen zu Parametertransformatoren finden Sie im Abschnitt Parametertransformatorreferenz.For more information on parameter transformers, see the Parameter transformer reference section.

Die folgende Tabelle enthält Beispielvorlagen für Routen und deren Verhalten:The following table demonstrates example route templates and their behavior:

RoutenvorlageRoute Template Beispiel-URI für ÜbereinstimmungExample Matching URI Der Anforderungs-URI…The request URI…
hello /hello Nur für den Pfad /hello wird eine Übereinstimmung ermittelt.Only matches the single path /hello.
{Page=Home} / Eine Übereinstimmung wird ermittelt, und Page wird auf Home festgelegt.Matches and sets Page to Home.
{Page=Home} /Contact Eine Übereinstimmung wird ermittelt, und Page wird auf Contact festgelegt.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Stimmt mit dem Products-Controller und der List-Aktion überein.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Stimmt mit dem Products-Controller und der Details-Aktion (mit id auf 123 festgelegt) überein.Maps to the Products controller and Details action withid set to 123.
{controller=Home}/{action=Index}/{id?} / Stimmt mit dem Home-Controller und der Index-Methode überein.Maps to the Home controller and Index method. id wird ignoriert.id is ignored.
{controller=Home}/{action=Index}/{id?} /Products Stimmt mit dem Products-Controller und der Index-Methode überein.Maps to the Products controller and Index method. id wird ignoriert.id is ignored.

Mit Vorlagen lässt sich Routing besonders leicht durchführen.Using a template is generally the simplest approach to routing. Einschränkungen und Standardwerte können auch außerhalb der Routenvorlage angegeben werden.Constraints and defaults can also be specified outside the route template.

Komplexe SegmenteComplex segments

Komplexe Segmente werden von rechts nach links auf eine nicht gierige Weise durch entsprechende Literaltrennzeichen verarbeitet.Complex segments are processed by matching up literal delimiters from right to left in a non-greedy way. Beispielsweise ist [Route("/a{b}c{d}")] ein komplexes Segment.For example, [Route("/a{b}c{d}")] is a complex segment. Komplexe Segmente funktionieren auf eine bestimmte Weise, die für eine erfolgreiche Verwendung verstanden werden muss.Complex segments work in a particular way that must be understood to use them successfully. Das Beispiel in diesem Abschnitt zeigt, warum komplexe Segmente nur dann wirklich gut funktionieren, wenn der Trennzeichentext nicht innerhalb der Parameterwerte erscheint.The example in this section demonstrates why complex segments only really work well when the delimiter text doesn't appear inside the parameter values. Für komplexere Fälle ist die Verwendung eines RegEx und das anschließende manuelle Extrahieren der Werte erforderlich.Using a regex and then manually extracting the values is needed for more complex cases.

Warnung

Übergeben Sie ein Timeout, wenn Sie System.Text.RegularExpressions zum Verarbeiten nicht vertrauenswürdiger Eingaben verwenden.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Ein böswilliger Benutzer kann Eingaben für RegularExpressions angeben, um einen Denial-of-Service-Angriff durchzuführen.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core-Framework-APIs, die RegularExpressions verwenden, übergeben ein Timeout.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Dies ist eine Zusammenfassung der Schritte, die beim Routing mit der Vorlage /a{b}c{d} und dem URL-Pfad /abcd ausgeführt werden.This is a summary of the steps that routing performs with the template /a{b}c{d} and the URL path /abcd. | wird verwendet, um die Funktionsweise des Algorithmus besser zu veranschaulichen:The | is used to help visualize how the algorithm works:

  • Das erste Literal von rechts nach links ist c.The first literal, right to left, is c. Daher wird /abcd von rechts durchsucht und /ab|c|d gefunden.So /abcd is searched from right and finds /ab|c|d.
  • Alles auf der rechten Seite (d) ist jetzt mit dem Routenparameter {d} abgeglichen.Everything to the right (d) is now matched to the route parameter {d}.
  • Das nächste Literal von rechts nach links ist a.The next literal, right to left, is a. Also wird /ab|c|d dort gesucht, wo die Suche unterbrochen wurde, und dann wird a in /|a|b|c|d gefunden.So /ab|c|d is searched starting where we left off, then a is found /|a|b|c|d.
  • Der Wert auf der rechten Seite (b) ist jetzt mit dem Routenparameter {b} abgeglichen.The value to the right (b) is now matched to the route parameter {b}.
  • Es ist kein verbleibender Text und keine verbleibende Routenvorlage vorhanden. Folglich ist dies eine Übereinstimmung.There is no remaining text and no remaining route template, so this is a match.

Nachfolgend ist ein Beispiel für einen negativen Fall mit derselben Vorlage /a{b}c{d} und dem URL-Pfad /aabcd.Here's an example of a negative case using the same template /a{b}c{d} and the URL path /aabcd. | wird verwendet, um die Funktionsweise des Algorithmus besser zu veranschaulichen:The | is used to help visualize how the algorithm works. Bei diesem Fall handelt es sich nicht um eine Übereinstimmung, was durch denselben Algorithmus belegt wird:This case isn't a match, which is explained by the same algorithm:

  • Das erste Literal von rechts nach links ist c.The first literal, right to left, is c. Daher wird /aabcd von rechts durchsucht und /aab|c|d gefunden.So /aabcd is searched from right and finds /aab|c|d.
  • Alles auf der rechten Seite (d) ist jetzt mit dem Routenparameter {d} abgeglichen.Everything to the right (d) is now matched to the route parameter {d}.
  • Das nächste Literal von rechts nach links ist a.The next literal, right to left, is a. Also wird /aab|c|d dort gesucht, wo die Suche unterbrochen wurde, und dann wird a in /a|a|b|c|d gefunden.So /aab|c|d is searched starting where we left off, then a is found /a|a|b|c|d.
  • Der Wert auf der rechten Seite (b) ist jetzt mit dem Routenparameter {b} abgeglichen.The value to the right (b) is now matched to the route parameter {b}.
  • Zu diesem Zeitpunkt gibt es noch verbleibenden Text a, aber es gibt keine Routenvorlage mehr, die der Algorithmus analysieren kann, weshalb dies keine Übereinstimmung ist.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.

Da der übereinstimmende Algorithmus nicht gierig ist:Since the matching algorithm is non-greedy:

  • Entspricht er der kleinstmöglichen Textmenge in jedem Schritt.It matches the smallest amount of text possible in each step.
  • Alle Fälle, in denen der Trennzeichenwert in den Parameterwerten angezeigt wird, stimmen nicht überein.Any case where the delimiter value appears inside the parameter values results in not matching.

Reguläre Ausdrücke bieten eine viel bessere Kontrolle über das Abgleichsverhalten.Regular expressions provide much more control over their matching behavior.

Beim gierigen Abgleich, auch als Lazy Matching bezeichnet, wird die größtmögliche Zeichenfolge abgeglichen.Greedy matching, also know as lazy matching, matches the largest possible string. Beim nicht gierigen Abgleich ist dies die kürzeste Zeichenfolge.Non-greedy matches the smallest possible string.

Referenz für RouteneinschränkungenRoute constraint reference

Routeneinschränkungen werden angewendet, wenn eine Übereinstimmung mit der eingehenden URL gefunden wurde und der URL-Pfad in Routenwerten mit Token versehen wird.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. In der Regel wird mit Routeneinschränkungen der Routenwert der zugehörigen Vorlage geprüft. Dabei wird anhand einer True/False-Entscheidung bestimmt, ob der Wert gültig ist.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. Für einige Routeneinschränkungen werden anstelle des Routenwerts andere Daten verwendet, um zu ermitteln, ob das Routing einer Anforderung möglich ist.Some route constraints use data outside the route value to consider whether the request can be routed. HttpMethodRouteConstraint kann beispielsweise auf der Grundlage des HTTP-Verbs eine Anforderung entweder annehmen oder ablehnen.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Einschränkungen werden in Routinganforderungen und bei der Linkgenerierung verwendet.Constraints are used in routing requests and link generation.

Warnung

Verwenden Sie keine Einschränkungen für die Eingabeüberprüfung.Don't use constraints for input validation. Wenn Einschränkungen für die Eingabevalidierung verwendet werden, führt eine ungültige Eingabe zu einem 404-Fehler (Nicht gefunden).If constraints are used for input validation, invalid input results in a 404 Not Found response. Eine ungültige Eingabe sollte zu einer ungültigen Anforderung (400) mit einer entsprechenden Fehlermeldung führen.Invalid input should produce a 400 Bad Request with an appropriate error message. Verwenden Sie Routeneinschränkungen nicht, um Eingaben für eine bestimmte Route zu überprüfen, sondern um ähnliche Routen zu unterscheiden.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

In der folgenden Tabelle werden Beispiele für Routeneinschränkungen und deren zu erwartendes Verhalten beschrieben:The following table demonstrates example route constraints and their expected behavior:

Einschränkungconstraint BeispielExample Beispiele für ÜbereinstimmungenExample Matches HinweiseNotes
int {id:int} 123456789, -123456789123456789, -123456789 Für jeden Integer wird eine Übereinstimmung ermittelt.Matches any integer
bool {active:bool} true, FALSEtrue, FALSE Entspricht true oder false.Matches true or false. Groß-/Kleinschreibung nicht beachtenCase-insensitive
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Entspricht einem gültigen DateTime-Wert in der invarianten Kultur.Matches a valid DateTime value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Entspricht einem gültigen decimal-Wert in der invarianten Kultur.Matches a valid decimal value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen double-Wert in der invarianten Kultur.Matches a valid double value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen float-Wert in der invarianten Kultur.Matches a valid float value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Für einen gültigen Guid-Wert wird eine Übereinstimmung ermittelt.Matches a valid Guid value
long {ticks:long} 123456789, -123456789123456789, -123456789 Für einen gültigen long-Wert wird eine Übereinstimmung ermittelt.Matches a valid long value
minlength(value) {username:minlength(4)} Rick Die Zeichenfolge muss mindestens eine Länge von 4 Zeichen aufweisen.String must be at least 4 characters
maxlength(value) {filename:maxlength(8)} MyFile Die Zeichenfolge darf maximal eine Länge von 8 Zeichen aufweisen.String must be no more than 8 characters
length(length) {filename:length(12)} somefile.txt Die Zeichenfolge muss genau 12 Zeichen aufweisen.String must be exactly 12 characters long
length(min,max) {filename:length(8,16)} somefile.txt Die Zeichenfolge muss mindestens eine Länge von 8 und darf maximal eine Länge von 16 Zeichen aufweisen.String must be at least 8 and no more than 16 characters long
min(value) {age:min(18)} 19 Der Integerwert muss mindestens 18 sein.Integer value must be at least 18
max(value) {age:max(120)} 91 Der Integerwert darf nicht größer als 120 sein.Integer value must be no more than 120
range(min,max) {age:range(18,120)} 91 Der Integerwert muss zwischen 18 und 120 liegen.Integer value must be at least 18 but no more than 120
alpha {name:alpha} Rick Die Zeichenfolge muss aus mindestens einem alphabetische Zeichen bestehen, a-z und ohne Unterscheidung zwischen Groß-/Kleinbuchstaben.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 Die Zeichenfolge muss mit dem regulären Ausdruck übereinstimmen.String must match the regular expression. Weitere Informationen finden Sie unter Tipps zum Definieren eines regulären Ausdrucks.See tips about defining a regular expression.
required {name:required} Rick Hierdurch wird erzwungen, dass ein Wert, der kein Parameter ist, für die URL-Generierung vorhanden sein muss.Used to enforce that a non-parameter value is present during URL generation

Warnung

Übergeben Sie ein Timeout, wenn Sie System.Text.RegularExpressions zum Verarbeiten nicht vertrauenswürdiger Eingaben verwenden.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Ein böswilliger Benutzer kann Eingaben für RegularExpressions angeben, um einen Denial-of-Service-Angriff durchzuführen.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core-Framework-APIs, die RegularExpressions verwenden, übergeben ein Timeout.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Auf einen einzelnen Parameter können mehrere durch Doppelpunkte getrennte Einschränkungen angewendet werden.Multiple, colon delimited constraints can be applied to a single parameter. Durch die folgende Einschränkung wird ein Parameter beispielsweise auf einen Integerwert größer oder gleich 1 beschränkt: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) { }

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden, wird immer die invariante Kultur verwendet.Route constraints that verify the URL and are converted to a CLR type always use the invariant culture. Dies gilt z. B. für die Konvertierung in den CLR-Typ int oder DateTime.For example, conversion to the CLR type int or DateTime. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.These constraints assume that the URL is not localizable. Die vom Framework bereitgestellten Routeneinschränkungen ändern nicht die Werte, die in Routenwerten gespeichert sind.The framework-provided route constraints don't modify the values stored in route values. Alle Routenwerte, die aus der URL analysiert werden, werden als Zeichenfolgen gespeichert.All route values parsed from the URL are stored as strings. Durch die float-Einschränkung wird beispielsweise versucht, den Routenwert in einen Gleitkommawert zu konvertieren. Mit dem konvertierten Wert wird allerdings nur überprüft, ob eine Umwandlung überhaupt möglich ist.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.

Reguläre Ausdrücke in EinschränkungenRegular expressions in constraints

Warnung

Übergeben Sie ein Timeout, wenn Sie System.Text.RegularExpressions zum Verarbeiten nicht vertrauenswürdiger Eingaben verwenden.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Ein böswilliger Benutzer kann Eingaben für RegularExpressions angeben, um einen Denial-of-Service-Angriff durchzuführen.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core-Framework-APIs, die RegularExpressions verwenden, übergeben ein Timeout.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Reguläre Ausdrücke können mithilfe der regex(...)-Routeneinschränkung als Inline-Einschränkungen angegeben werden.Regular expressions can be specified as inline constraints using the regex(...) route constraint. Methoden der MapControllerRoute-Familie akzeptieren auch ein Objektliteral von Einschränkungen.Methods in the MapControllerRoute family also accept an object literal of constraints. Wenn dieses Formular verwendet wird, werden Zeichenfolgenwerte als reguläre Ausdrücke interpretiert.If that form is used, string values are interpreted as regular expressions.

Der folgende Code verwendet eine Inline-RegEx-Einschränkung: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");
        });
 });

Der folgende Code verwendet ein Objektliteral, um eine RegEx-Einschränkung anzugeben: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", });
});

Im ASP.NET Core-Framework wird dem Konstruktor für reguläre Ausdrücke RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant hinzugefügt.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Eine Beschreibung dieser Member finden Sie unter RegexOptions.See RegexOptions for a description of these members.

In regulären Ausdrücken werden Trennzeichen und Token verwendet, die auch beim Routing und in der Programmiersprache C# in ähnlicher Weise verwendet werden.Regular expressions use delimiters and tokens similar to those used by routing and the C# language. Token, die reguläre Ausdrücke enthalten, müssen mit einem Escapezeichen versehen werden.Regular expression tokens must be escaped. Wenn Sie den regulären Ausdruck ^\d{3}-\d{2}-\d{4}$ in einer Inline-Einschränkung verwenden möchten, nutzen Sie eine der folgenden Optionen:To use the regular expression ^\d{3}-\d{2}-\d{4}$ in an inline constraint, use one of the following:

  • Ersetzen Sie \-Zeichen in der Zeichenfolge durch \\-Zeichen in der C#-Quelldatei, um das Escapezeichen für die Zeichenfolge \ zu setzen.Replace \ characters provided in the string as \\ characters in the C# source file in order to escape the \ string escape character.
  • Ausführliche ZeichenfolgeliteraleVerbatim string literals.

Wenn Sie Trennzeichen für Routenparameter mit Escapezeichen versehen möchten ({, }, [, ]), geben Sie jedes Zeichen im Ausdruck doppelt ein (z. B. {{, }}, [[, ]]).To escape routing parameter delimiter characters {, }, [, ], double the characters in the expression, for example, {{, }}, [[, ]]. In der folgenden Tabelle werden reguläre Ausdrücke und Ausdrücke aufgeführt, die mit Escapezeichen versehen sind:The following table shows a regular expression and its escaped version:

Regulärer AusdruckRegular expression Mit Escapezeichen versehener regulärer AusdruckEscaped regular expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Beim Routing verwendete reguläre Ausdrücke beginnen oft mit dem ^-Zeichen und stellen die Startposition der Zeichenfolge dar.Regular expressions used in routing often start with the ^ character and match the starting position of the string. Die Ausdrücke enden häufig mit einem Dollarzeichen ($) und stellen das Ende der Zeichenfolge dar.The expressions often end with the $ character and match the end of the string. Mit den Zeichen ^ und $ wird sichergestellt, dass der reguläre Ausdruck mit dem vollständigen Routenparameterwert übereinstimmt.The ^ and $ characters ensure that the regular expression matches the entire route parameter value. Ohne die Zeichen ^ und $ werden mit dem regulären Ausdruck alle Teilzeichenfolgen ermittelt, was häufig nicht gewünscht ist.Without the ^ and $ characters, the regular expression matches any substring within the string, which is often undesirable. In der folgenden Tabelle finden Sie Beispiele für reguläre Ausdrücke. Außerdem wird erklärt, warum ein Abgleich erfolgreich ist oder fehlschlägt:The following table provides examples and explains why they match or fail to match:

expressionExpression ZeichenfolgeString MatchMatch KommentarComment
[a-z]{2} hellohello JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} 123abc456123abc456 JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} mzmz JaYes Ausdruck stimmt übereinMatches expression
[a-z]{2} MZMZ JaYes keine Unterscheidung zwischen Groß-/KleinbuchstabenNot case sensitive
^[a-z]{2}$ hellohello NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above

Weitere Informationen zur Syntax von regulären Ausdrücken finden Sie unter Sprachelemente für reguläre Ausdrücke – Kurzübersicht.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Einen regulären Ausdruck können Sie verwenden, um einen Parameter auf zulässige Werte einzuschränken.To constrain a parameter to a known set of possible values, use a regular expression. Mit {action:regex(^(list|get|create)$)} werden beispielsweise für den action-Routenwert nur die Werte list, get oder create abgeglichen.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Wenn die Zeichenfolge ^(list|get|create)$ dem Einschränkungswörterbuch übergeben wird, führt dies zum gleichen Ergebnis.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Auch Einschränkungen, die dem zugehörigen Wörterbuch hinzugefügt werden und mit keiner vorgegebenen Einschränkung übereinstimmen, werden als reguläre Ausdrücke behandelt.Constraints that are passed in the constraints dictionary that don't match one of the known constraints are also treated as regular expressions. Einschränkungen, die innerhalb einer Vorlage übergeben werden und mit keiner vorgegebenen Einschränkung übereinstimmen, werden nicht als reguläre Ausdrücke behandelt.Constraints that are passed within a template that don't match one of the known constraints are not treated as regular expressions.

Benutzerdefinierte RouteneinschränkungenCustom route constraints

Benutzerdefinierte Routeneinschränkungen können durch Implementierung der IRouteConstraint-Schnittstelle erstellt werden.Custom route constraints can be created by implementing the IRouteConstraint interface. Die IRouteConstraint-Schnittstelle umfasst die Match-Methode, die true zurückgibt, wenn die Einschränkung erfüllt wird, und andernfalls false.The IRouteConstraint interface contains Match, which returns true if the constraint is satisfied and false otherwise.

Benutzerdefinierte Routeneinschränkungen werden nur selten benötigt.Custom route constraints are rarely needed. Bevor Sie eine benutzerdefinierte Routeneinschränkung implementieren, sollten Sie Alternativen in Betracht ziehen, wie z. B. Modellbindung.Before implementing a custom route constraint, consider alternatives, such as model binding.

Der ASP.NET Core-Ordner Constraints bietet nützliche Beispiele für die Erstellung einer Einschränkung.The ASP.NET Core Constraints folder provides good examples of creating a constraints. Beispiel: GuidRouteConstraint.For example, GuidRouteConstraint.

Zum Verwenden eines benutzerdefinierten IRouteConstraint-Elements muss der Routeneinschränkungstyp bei der ConstraintMap-Eigenschaft der App im Dienstcontainer registriert werden.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the service container. Eine ConstraintMap ist ein Wörterbuch, das Routeneinschränkungsschlüssel IRouteConstraint-Implementierungen zuordnet, die diese Einschränkungen überprüfen.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Die ConstraintMap einer App kann in Startup.ConfigureServices entweder als Teil eines services.AddRouting-Aufrufs oder durch direktes Konfigurieren von RouteOptions mit services.Configure<RouteOptions> aktualisiert werden.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>. Zum Beispiel:For example:

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

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

Die vorangehende Einschränkung wird im folgenden Code angewendet: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 wird von dem NuGet-Paket Rick.Docs.Samples.RouteInfo bereitgestellt und zeigt Routeninformationen an.MyDisplayRouteInfo is provided by the Rick.Docs.Samples.RouteInfo NuGet package and displays route information.

Die Implementierung von MyCustomConstraint verhindert die Anwendung von 0 auf einen Routenparameter: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;
    }
}

Warnung

Übergeben Sie ein Timeout, wenn Sie System.Text.RegularExpressions zum Verarbeiten nicht vertrauenswürdiger Eingaben verwenden.When using System.Text.RegularExpressions to process untrusted input, pass a timeout. Ein böswilliger Benutzer kann Eingaben für RegularExpressions angeben, um einen Denial-of-Service-Angriff durchzuführen.A malicious user can provide input to RegularExpressions causing a Denial-of-Service attack. ASP.NET Core-Framework-APIs, die RegularExpressions verwenden, übergeben ein Timeout.ASP.NET Core framework APIs that use RegularExpressions pass a timeout.

Der vorangehende Code:The preceding code:

  • Verhindert, dass 0 im {id}-Segment der Route vorhanden ist.Prevents 0 in the {id} segment of the route.
  • Dient als einfaches Beispiel für die Implementierung einer benutzerdefinierten Einschränkung.Is shown to provide a basic example of implementing a custom constraint. Es sollte nicht in einer Produktions-App eingesetzt werden.It should not be used in a production app.

Der folgende Code bietet einen besseren Ansatz, um zu verhindern, dass eine id mit einer 0 verarbeitet wird: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);
}

Der vorangehende Code bietet im Vergleich zum MyCustomConstraint-Ansatz folgende Vorteile:The preceding code has the following advantages over the MyCustomConstraint approach:

  • Eine benutzerdefinierte Einschränkung ist nicht erforderlich.It doesn't require a custom constraint.
  • Es wird ein beschreibender Fehler zurückgegeben, wenn der Routenparameter 0 enthält.It returns a more descriptive error when the route parameter includes 0.

ParametertransformatorreferenzParameter transformer reference

Parametertransformatoren:Parameter transformers:

Beispielsweise generiert ein benutzerdefinierter Parametertransformator slugify im Routenmuster blog\{article:slugify} mit Url.Action(new { article = "MyTestArticle" })``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.

Betrachten Sie die folgende Implementierung von IOutboundParameterTransformer: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();
    }
}

Um einen Parametertransformator in einem Routenmuster zu verwenden, konfigurieren Sie ihn mit ConstraintMap in 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);
    });
}

Das ASP.NET Core-Framework verwendet Parametertransformatoren, um den URI zu transformieren, zu dem ein Endpunkt aufgelöst wird.The ASP.NET Core framework uses parameter transformers to transform the URI where an endpoint resolves. Beispielsweise wandeln Parametertransformatoren die Routenwerte um, die zum Zuordnen folgender Elemente verwendet werden: area, controller, action und 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?}");

Mit der vorstehenden Routenvorlage wird die Aktion SubscriptionManagementController.GetAll dem URI /subscription-management/get-all zugeordnet.With the preceding route template, the action SubscriptionManagementController.GetAll is matched with the URI /subscription-management/get-all. Ein Parametertransformator ändert nicht die zum Generieren eines Links verwendeten Routenwerte.A parameter transformer doesn't change the route values used to generate a link. Beispielsweise gibt Url.Action("GetAll", "SubscriptionManagement")``/subscription-management/get-all aus.For example, Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core bietet API-Konventionen für die Verwendung von Parametertransformatoren mit generierten Routen:ASP.NET Core provides API conventions for using parameter transformers with generated routes:

Referenz für URL-GenerierungURL generation reference

Dieser Abschnitt enthält eine Referenz für den Algorithmus, der durch die URL-Generierung implementiert wird.This section contains a reference for the algorithm implemented by URL generation. In der Praxis werden bei den meisten komplexen Beispielen für die URL-Generierung Controller oder Razor Pages verwendet.In practice, most complex examples of URL generation use controllers or Razor Pages. Weitere Informationen finden Sie unter Routing in Controllern (Routing in Controllern).See routing in controllers for additional information.

Die URL-Generierung beginnt mit einem Aufruf von LinkGenerator.GetPathByAddress oder einer ähnlichen Methode.The URL generation process begins with a call to LinkGenerator.GetPathByAddress or a similar method. Die Methode wird mit einer Adresse, mehreren Routenwerten und optional mit Informationen zur aktuellen Anforderung von HttpContext versehen.The method is provided with an address, a set of route values, and optionally information about the current request from HttpContext.

Im ersten Schritt wird die Adresse verwendet, um bestimmte Endpunktkandidaten mithilfe einer IEndpointAddressScheme<TAddress>-Schnittstelle aufzulösen, die dem Adresstyp entspricht.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.

Sobald eine Kandidatengruppe anhand des Adressschemas gefunden wurde, werden die Endpunkte geordnet und iterativ verarbeitet, bis die URL-Generierung erfolgreich abgeschlossen ist.Once of set of candidates is found by the address scheme, the endpoints are ordered and processed iteratively until a URL generation operation succeeds. Bei der URL-Generierung wird nicht auf Mehrdeutigkeiten geprüft, daher ist das erste zurückgegebene Ergebnis das Endergebnis.URL generation does not check for ambiguities, the first result returned is the final result.

Behandeln von Problemen mit der Protokollierung bei der URL-GenerierungTroubleshooting URL generation with logging

Der erste Schritt bei der Behebung von Problemen bei der URL-Generierung ist die Einstellung des Protokolliergrads von Microsoft.AspNetCore.Routing auf TRACE.The first step in troubleshooting URL generation is setting the logging level of Microsoft.AspNetCore.Routing to TRACE. LinkGenerator protokolliert viele Details über die Verarbeitung, die bei der Problembehebung nützlich sein können.LinkGenerator logs many details about its processing which can be useful to troubleshoot problems.

Ausführliche Informationen zur URL-Generierung finden Sie unter Referenz für URL-Generierung.See URL generation reference for details on URL generation.

AdressenAddresses

Mithilfe von Adressen wird bei der URL-Generierung ein Aufruf in der API zur Linkgenerierung an mehrere Endpunktkandidaten gebunden.Addresses are the concept in URL generation used to bind a call into the link generator to a set of candidate endpoints.

Adressen sind ein erweiterbares Konzept, das standardmäßig mit zwei Implementierungen bereitgestellt wird:Addresses are an extensible concept that come with two implementations by default:

  • Die Verwendung von Endpunktname (string) als Adresse:Using endpoint name (string) as the address:
    • Bietet ähnliche Funktionalität wie der Routenname von MVC.Provides similar functionality to MVC's route name.
    • Wird der IEndpointNameMetadata-Metadatentyp verwendet.Uses the IEndpointNameMetadata metadata type.
    • Löst die bereitgestellte Zeichenfolge anhand der Metadaten aller registrierten Endpunkte auf.Resolves the provided string against the metadata of all registered endpoints.
    • Löst beim Start eine Ausnahme aus, wenn mehrere Endpunkte den gleichen Namen aufweisen.Throws an exception on startup if multiple endpoints use the same name.
    • Wird für die allgemeine Verwendung außerhalb von Controllern und Razor Pages empfohlen.Recommended for general-purpose use outside of controllers and Razor Pages.
  • Die Verwendung von Routenwerten (RouteValuesAddress) als Adresse:Using route values (RouteValuesAddress) as the address:
    • Bietet eine ähnliche Funktionalität wie die veraltete Funktion zur URL-Generierung von Controllern und Razor Pages.Provides similar functionality to controllers and Razor Pages legacy URL generation.
    • Lässt sich nur schwer erweitern und debuggen.Very complex to extend and debug.
    • Bietet die Implementierung, die von IUrlHelper, Taghilfsprogrammen, HTML-Hilfsprogrammen, Aktionsergebnissen usw. verwendet wird.Provides the implementation used by IUrlHelper, Tag Helpers, HTML Helpers, Action Results, etc.

Aufgabe des Adressschemas ist es, die Verbindung zwischen der Adresse und den übereinstimmenden Endpunkten anhand von beliebigen Kriterien herzustellen:The role of the address scheme is to make the association between the address and matching endpoints by arbitrary criteria:

  • Das Schema für Endpunktenamen führt eine allgemeine Wörterbuchsuche durch.The endpoint name scheme performs a basic dictionary lookup.
  • Das Schema der Routenwerte weist eine komplexe beste Teilmenge des Mengenalgorithmus auf.The route values scheme has a complex best subset of set algorithm.

Umgebungswerte und explizite WerteAmbient values and explicit values

Aus der aktuellen Anforderung greift das Routing auf die Routenwerte der aktuellen Anforderung HttpContext.Request.RouteValues zu.From the current request, routing accesses the route values of the current request HttpContext.Request.RouteValues. Die mit der aktuellen Anforderung verbundenen Werte werden als Umgebungswerte bezeichnet.The values associated with the current request are referred to as the ambient values. Aus Gründen der Übersichtlichkeit werden in der Dokumentation die an die Methoden übergebenen Routenwerte als explizite Werte bezeichnet.For the purpose of clarity, the documentation refers to the route values passed in to methods as explicit values.

Das folgende Beispiel zeigt Umgebungswerte und explizite Werte.The following example shows ambient values and explicit values. Er liefert Umgebungswerte aus der aktuellen Anforderung und explizite Werte: { 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);
    }

Der vorangehende Code:The preceding code:

Der folgende Code liefert keine Umgebungswerte und keine expliziten Werte: { 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);
}

Die vorhergehende Methode gibt /Home/Subscribe/17 zurückThe preceding method returns /Home/Subscribe/17

Der folgende Code in WidgetController gibt /Widget/Subscribe/17 zurück:The following code in the WidgetController returns /Widget/Subscribe/17:

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

Der folgende Code stellt den Controller aus den Umgebungswerten in der aktuellen Anforderung und explizite Werte dar: { 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);
    }

Für den Code oben gilt:In the preceding code:

  • /Gadget/Edit/17 wird zurückgegeben./Gadget/Edit/17 is returned.
  • Url ruft die IUrlHelper-Schnittstelle ab.Url gets the IUrlHelper.
  • Action
    generiert eine URL mit einem absoluten Pfad für eine Aktionsmethode.generates a URL with an absolute path for an action method. Die URL enthält den angegebenen action-Namen und route-Werte.The URL contains the specified action name and route values.

Sie liefert Umgebungswerte aus der aktuellen Anforderung und explizite Werte: { 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;
    }
}

Im vorangehenden Code wird url auf /Edit/17 festgelegt, wenn die Option zum Bearbeiten der Razor Page die folgende Seitenanweisung enthält:The preceding code sets url to /Edit/17 when the Edit Razor Page contains the following page directive:

@page "{id:int}"

Wenn die Routenvorlage "{id:int}" nicht in der Seite „Bearbeiten“ enthalten ist, ist url gleich /Edit?id=17.If the Edit page doesn't contain the "{id:int}" route template, url is /Edit?id=17.

Das Verhalten der IUrlHelper-Schnittstelle von MVC fügt zusätzlich zu den hier beschriebenen Regeln eine weitere Komplexitätsebene hinzu:The behavior of MVC's IUrlHelper adds a layer of complexity in addition to the rules described here:

  • IUrlHelper liefert immer die Routenwerte aus der aktuellen Anforderung als Umgebungswerte.IUrlHelper always provides the route values from the current request as ambient values.
  • IUrlHelper.action kopiert immer die aktuellen Routenwerte action und controller als explizite Werte, sofern sie nicht vom Entwickler außer Kraft gesetzt werden.IUrlHelper.Action always copies the current action and controller route values as explicit values unless overridden by the developer.
  • IUrlHelper.page kopiert immer den aktuellen Routenwert page als expliziten Wert, sofern er nicht außer Kraft gesetzt wird.IUrlHelper.Page always copies the current page route value as an explicit value unless overridden.
  • IUrlHelper.Page setzt immer den aktuellen Routenwert handler mit null als expliziten Wert außer Kraft, sofern er nicht außer Kraft gesetzt wird.IUrlHelper.Page always overrides the current handler route value with null as an explicit values unless overridden.

Benutzer sind oft von den Verhaltensdetails der Umgebungswerte überrascht, da MVC anscheinend nicht den eigenen Regeln folgt.Users are often surprised by the behavioral details of ambient values, because MVC doesn't seem to follow its own rules. Aus Verlaufs- und Kompatibilitätsgründen weisen bestimmte Routenwerte wie action, controller, page und handler ein spezielles Verhalten auf.For historical and compatibility reasons, certain route values such as action, controller, page, and handler have their own special-case behavior.

Die äquivalente Funktionalität, die durch LinkGenerator.GetPathByAction und LinkGenerator.GetPathByPage bereitgestellt wird, verdoppelt diese Anomalien von IUrlHelper aus Kompatibilitätsgründen.The equivalent functionality provided by LinkGenerator.GetPathByAction and LinkGenerator.GetPathByPage duplicates these anomalies of IUrlHelper for compatibility.

URL-GenerierungsprozessURL generation process

Sobald die Gruppe der Endpunktkandidaten ermittelt ist, wird der URL-Generierungsalgorithmus angewendet:Once the set of candidate endpoints are found, the URL generation algorithm:

  • Die Endpunkte werden iterativ verarbeitet.Processes the endpoints iteratively.
  • Das erste erfolgreiche Ergebnis wird zurückgegeben.Returns the first successful result.

Der erste Schritt in diesem Prozess wird als Routenwertinvalidierung bezeichnet.The first step in this process is called route value invalidation. Die Routenwertinvalidierung ist der Prozess, bei dem das Routing entscheidet, welche Routenwerte aus den Umgebungswerten verwendet und welche ignoriert werden sollen.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. Jeder Umgebungswert wird berücksichtigt und entweder mit den expliziten Werten kombiniert oder aber ignoriert.Each ambient value is considered and either combined with the explicit values, or ignored.

Denken Sie daran, dass Umgebungswerte Anwendungsentwicklern in allgemeinen Fällen das Schreiben von Code sparen können.The best way to think about the role of ambient values is that they attempt to save application developers typing, in some common cases. In der Regel sind die Szenarios, in denen Umgebungswerte hilfreich sind, mit MVC verknüpft:Traditionally, the scenarios where ambient values are helpful are related to MVC:

  • Bei der Verknüpfung mit einer anderen Aktion im gleichen Controller muss der Controllername nicht angegeben werden.When linking to another action in the same controller, the controller name doesn't need to be specified.
  • Bei der Verknüpfung mit einem anderen Controller im gleichen Bereich muss der Bereich nicht angegeben werden.When linking to another controller in the same area, the area name doesn't need to be specified.
  • Bei der Verknüpfung mit der gleichen Aktionsmethode müssen keine Routenwerte angegeben werden.When linking to the same action method, route values don't need to be specified.
  • Bei der Verknüpfung mit einem anderen Teil der App sollen keine Routenwerte übertragen werden, die für diesen Teil der App irrelevant sind.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.

Aufrufe an LinkGenerator oder IUrlHelper, die null zurückgeben, sind meist dadurch bedingt, dass die Routenwertinvalidierung nicht verstanden wurde.Calls to LinkGenerator or IUrlHelper that return null are usually caused by not understanding route value invalidation. Beheben Sie die Routenwertinvalidierung, indem Sie explizit mehr Routenwerte angeben, um zu prüfen, ob das Problem dadurch gelöst wird.Troubleshoot route value invalidation by explicitly specifying more of the route values to see if that solves the problem.

Bei der Routenwertinvalidierung wird davon ausgegangen, dass das URL-Schema der Anwendung hierarchisch ist, mit einer von links nach rechts gebildeten Hierarchie.Route value invalidation works on the assumption that the app's URL scheme is hierarchical, with a hierarchy formed from left-to-right. Sehen Sie sich die einfache Controllerroutenvorlage {controller}/{action}/{id?} an, um ein Gespür dafür zu bekommen, wie dies in der Praxis funktioniert.Consider the basic controller route template {controller}/{action}/{id?} to get an intuitive sense of how this works in practice. Durch eine Änderung auf einen Wert werden alle rechts angezeigten Routenwerte ungültig.A change to a value invalidates all of the route values that appear to the right. Dies spricht für die These von der Hierarchie.This reflects the assumption about hierarchy. Wenn die App einen Umgebungswert für id hat und der Vorgang einen anderen Wert für controller angibt:If the app has an ambient value for id, and the operation specifies a different value for the controller:

  • id wird nicht wiederverwendet, weil {controller} links von {id?} steht.id won't be reused because {controller} is to the left of {id?}.

Einige Beispiele veranschaulichen dieses Prinzip:Some examples demonstrating this principle:

  • Wenn die expliziten Werte einen Wert für id enthalten, wird der Umgebungswert für id ignoriert.If the explicit values contain a value for id, the ambient value for id is ignored. Die Umgebungswerte für controller und action können verwendet werden.The ambient values for controller and action can be used.
  • Wenn die expliziten Werte einen Wert für action enthalten, wird jeder Umgebungswert für action ignoriert.If the explicit values contain a value for action, any ambient value for action is ignored. Die Umgebungswerte für controller können verwendet werden.The ambient values for controller can be used. Wenn sich der explizite Wert für action von dem Umgebungswert für action unterscheidet, wird der Wert id nicht verwendet.If the explicit value for action is different from the ambient value for action, the id value won't be used. Wenn der explizite Wert für action mit dem Umgebungswert für action übereinstimmt, kann der Wert id verwendet werden.If the explicit value for action is the same as the ambient value for action, the id value can be used.
  • Wenn die expliziten Werte einen Wert für controller enthalten, wird jeder Umgebungswert für controller ignoriert.If the explicit values contain a value for controller, any ambient value for controller is ignored. Wenn sich der explizite Wert für controller von dem Umgebungswert für controller unterscheidet, werden die Werte action und id nicht verwendet.If the explicit value for controller is different from the ambient value for controller, the action and id values won't be used. Wenn der explizite Wert für controller mit dem Umgebungswert für controller übereinstimmt, können die Werte action und id verwendet werden.If the explicit value for controller is the same as the ambient value for controller, the action and id values can be used.

Dieser Prozess wird zusätzlich durch die vorhandenen Attributrouten und dedizierten konventionellen Routen erschwert.This process is further complicated by the existence of attribute routes and dedicated conventional routes. Konventionelle Routen des Controllers wie {controller}/{action}/{id?} legen eine Hierarchie mithilfe von Routenparametern fest.Controller conventional routes such as {controller}/{action}/{id?} specify a hierarchy using route parameters. Bei bestimmten konventionellen Routen und Attributrouten zu Controllern und Razor Pages:For dedicated conventional routes and attribute routes to controllers and Razor Pages:

  • Gibt es eine Hierarchie für Routenwerte.There is a hierarchy of route values.
  • Werden diese nicht in der Vorlage angezeigt.They don't appear in the template.

Für diese Fälle definiert die URL-Generierung das Konzept der erforderlichen Werte.For these cases, URL generation defines the required values concept. Bei Endpunkten, die von Controllern und Razor Pages erstellt wurden, sind erforderliche Werte angegeben, die eine Routenwertinvalidierung ermöglichen.Endpoints created by controllers and Razor Pages have required values specified that allow route value invalidation to work.

Der Algorithmus der Routenwertinvalidierung im Detail:The route value invalidation algorithm in detail:

  • Die erforderlichen Wertnamen werden mit den Routenparametern kombiniert und dann von links nach rechts verarbeitet.The required value names are combined with the route parameters, then processed from left-to-right.
  • Für jeden Parameter werden der Umgebungswert und der explizite Wert verglichen:For each parameter, the ambient value and explicit value are compared:
    • Wenn der Umgebungswert und der explizite Wert gleich sind, wird der Prozess fortgesetzt.If the ambient value and explicit value are the same, the process continues.
    • Wenn der Umgebungswert vorhanden ist und der explizite Wert nicht, wird der Umgebungswert bei der URL-Generierung verwendet.If the ambient value is present and the explicit value isn't, the ambient value is used when generating the URL.
    • Wenn der Umgebungswert nicht vorhanden ist und der explizite Wert vorhanden ist, verwerfen Sie den Umgebungswert und alle nachfolgenden Umgebungswerte.If the ambient value isn't present and the explicit value is, reject the ambient value and all subsequent ambient values.
    • Wenn der Umgebungswert und der explizite Wert vorhanden und die beiden Werte unterschiedlich sind, verwerfen Sie den Umgebungswert und alle nachfolgenden Umgebungswerte.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.

An diesem Punkt ist der Vorgang zur URL-Generierung bereit, Routeneinschränkungen auszuwerten.At this point, the URL generation operation is ready to evaluate route constraints. Die akzeptierten Werte werden mit den Standardwerten der Parameter kombiniert, die für Einschränkungen bereitgestellt werden.The set of accepted values is combined with the parameter default values, which is provided to constraints. Wenn alle Einschränkungen erfüllt sind, wird der Vorgang fortgesetzt.If the constraints all pass, the operation continues.

Als Nächstes können die akzeptierten Werte verwendet werden, um die Routenvorlage zu erweitern.Next, the accepted values can be used to expand the route template. Die Routenvorlage wird verarbeitet:The route template is processed:

  • Von links nach rechts.From left-to-right.
  • Für jeden Parameter wird der akzeptierte Wert ersetzt.Each parameter has its accepted value substituted.
  • In den folgenden Sonderfällen:With the following special cases:
    • Wenn bei den akzeptierten Werten ein Wert fehlt und der Parameter einen Standardwert hat, wird der Standardwert verwendet.If the accepted values is missing a value and the parameter has a default value, the default value is used.
    • Wenn bei den akzeptierten Werten ein Wert fehlt und der Parameter optional ist, wird die Verarbeitung fortgesetzt.If the accepted values is missing a value and the parameter is optional, processing continues.
    • Wenn irgendein Routenparameter rechts neben einem fehlenden optionalen Parameter einen Wert hat, schlägt der Vorgang fehl.If any route parameter to the right of a missing optional parameter has a value, the operation fails.
    • Zusammenhängende Parameter mit Standardwerten und optionale Parameter werden, wenn möglich, reduziert dargestellt.Contiguous default-valued parameters and optional parameters are collapsed where possible.

Explizit bereitgestellte Werte, für die keine Übereinstimmungen mit einem Routensegment ermittelt werden, werden der Abfragezeichenfolge hinzugefügt.Values explicitly provided that don't match a segment of the route are added to the query string. In der folgenden Tabelle werden die Ergebnisse dargestellt, die aus der Verwendung der Routenvorlage {controller}/{action}/{id?} hervorgehen:The following table shows the result when using the route template {controller}/{action}/{id?}.

UmgebungswerteAmbient Values Explizite WerteExplicit Values ErgebnisResult
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

Probleme mit der RoutenwertinvalidierungProblems with route value invalidation

Ab ASP.NET Core 3.0 funktionieren einige Schemas zur URL-Generierung, die in früheren ASP.NET Core-Versionen verwendet wurden, nicht mehr sehr gut.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. Das ASP.NET Core-Team plant, in einer zukünftigen Version Features hinzuzufügen, die diese Anforderungen erfüllen.The ASP.NET Core team plans to add features to address these needs in a future release. Im Moment ist die beste Lösung die Verwendung von Legacy-Routingfunktionen.For now the best solution is to use legacy routing.

Der folgende Code zeigt ein Beispiel für ein Schema zur URL-Generierung, das vom Routing nicht unterstützt wird.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", });
});

Im vorangehenden Code wird der culture-Routenparameter für die Lokalisierung verwendet.In the preceding code, the culture route parameter is used for localization. Ziel ist es, dass der culture-Parameter immer als Umgebungswert akzeptiert wird.The desire is to have the culture parameter always accepted as an ambient value. Der culture-Parameter wird jedoch aufgrund der Art und Weise, wie die erforderlichen Werte funktionieren, nicht als Umgebungswert akzeptiert:However, the culture parameter is not accepted as an ambient value because of the way required values work:

  • In der "default"-Routenvorlage befindet sich der culture-Routenparameter links von controller, sodass culture durch Änderungen an controller nicht ungültig wird.In the "default" route template, the culture route parameter is to the left of controller, so changes to controller won't invalidate culture.
  • In der "blog"-Routenvorlage wird der culture-Routenparameter rechts von controller betrachtet, der in den erforderlichen Werten aufgeführt ist.In the "blog" route template, the culture route parameter is considered to be to the right of controller, which appears in the required values.

Konfigurieren von EndpunktmetadatenConfiguring endpoint metadata

Die folgenden Links enthalten Informationen zum Konfigurieren von Endpunktmetadaten:The following links provide information on configuring endpoint metadata:

Hostabgleich in Routen mit RequireHostHost matching in routes with RequireHost

RequireHost wendet eine Einschränkung auf die Route an, für die der angegebene Host erforderlich ist.RequireHost applies a constraint to the route which requires the specified host. Der RequireHost- oder [Host]-Parameter kann wie folgt lauten:The RequireHost or [Host] parameter can be:

  • Host: www.domain.com, entspricht www.domain.com mit einem beliebigen Port.Host: www.domain.com, matches www.domain.com with any port.
  • Host mit Platzhalter: *.domain.com, entspricht www.domain.com, subdomain.domain.com oder www.subdomain.domain.com an einem beliebigen Port.Host with wildcard: *.domain.com, matches www.domain.com, subdomain.domain.com, or www.subdomain.domain.com on any port.
  • Port: *:5000, entspricht Port 5000 mit einem beliebigen Host.Port: *:5000, matches port 5000 with any host.
  • Host und Port: www.domain.com:5000 oder *.domain.com:5000, entspricht dem Host und Port.Host and port: www.domain.com:5000 or *.domain.com:5000, matches host and port.

Es können mehrere Parameter mit RequireHost oder [Host] angegeben werden.Multiple parameters can be specified using RequireHost or [Host]. Die Einschränkung gleicht die Hosts ab, die für einen der Parameter gültig sind.The constraint matches hosts valid for any of the parameters. Beispielsweise entspricht [Host("domain.com", "*.domain.com")] domain.com, www.domain.com und subdomain.domain.com.For example, [Host("domain.com", "*.domain.com")] matches domain.com, www.domain.com, and subdomain.domain.com.

Im folgenden Code wird RequireHost verwendet, um den angegebenen Host auf der Route anzufordern: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");
    });
}

Im folgenden Code wird das [Host]-Attribut für den Controller verwendet, um die einzelnen angegebenen Hosts anzufordern: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();
    }
}

Wenn das [Host]-Attribut sowohl auf die Controller- als auch auf die Aktionsmethode angewendet wird, trifft Folgendes zu:When the [Host] attribute is applied to both the controller and action method:

  • Das Attribut auf der Aktion wird verwendet.The attribute on the action is used.
  • Das Controllerattribut wird ignoriert.The controller attribute is ignored.

Leistungsleitfaden für das RoutingPerformance guidance for routing

Der Großteil der Routingfunktionalität wurde in ASP.NET Core 3.0 aktualisiert, um die Leistung zu erhöhen.Most of routing was updated in ASP.NET Core 3.0 to increase performance.

Wenn eine App Leistungsprobleme hat, wird die Ursache häufig beim Routing vermutet.When an app has performance problems, routing is often suspected as the problem. Das Routing wird deshalb in Betracht gezogen, weil Frameworks wie Controller und Razor Pages in ihren Protokollierungsmeldungen die innerhalb des Frameworks verbrachte Zeit angeben.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. Wenn es einen signifikanten Unterschied zwischen der von den Controllern gemeldeten Zeit und der Gesamtzeit der Anforderung gibt:When there's a significant difference between the time reported by controllers and the total time of the request:

  • Schließen Entwickler ihren App-Code als Ursache des Problems aus.Developers eliminate their app code as the source of the problem.
  • Wird in der Regel angenommen, dass das Routing die Ursache für das Problem ist.It's common to assume routing is the cause.

Die Leistung des Routings wird anhand von Tausenden von Endpunkten getestet.Routing is performance tested using thousands of endpoints. Es ist unwahrscheinlich, dass eine typische App auf ein Leistungsproblem stößt, nur weil diese zu umfangreich ist.It's unlikely that a typical app will encounter a performance problem just by being too large. Die häufigste Ursache für eine langsames Routing ist üblicherweise eine schlecht funktionierende benutzerdefinierte Middleware.The most common root cause of slow routing performance is usually a badly-behaving custom middleware.

Das folgende Codebeispiel veranschaulicht eine grundlegende Technik zur Eingrenzung der Verzögerungsquelle: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.");
        });
    });
}

Auf das Zeitrouting:To time routing:

  • Verschachteln Sie jede Middleware mit einer Kopie der im vorherigen Code gezeigten Zeitmiddleware.Interleave each middleware with a copy of the timing middleware shown in the preceding code.
  • Fügen Sie einen eindeutigen Bezeichner hinzu, um die Zeitdaten mit dem Code zu korrelieren.Add a unique identifier to correlate the timing data with the code.

Dies ist ein einfacher Weg, um die Verzögerung zu verringern, wenn sie signifikant ist, zum Beispiel größer als 10ms.This is a basic way to narrow down the delay when it's significant, for example, more than 10ms. Wenn Time 2 von Time 1 subtrahiert wird, ergibt sich die in der UseRouting-Middleware benötigte Zeit.Subtracting Time 2 from Time 1 reports the time spent inside the UseRouting middleware.

Der folgende Code verwendet einen kompakteren Ansatz als der vorangegangene Zeitcode: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.");
        });
    });
}

Potenziell teure RoutingfeaturesPotentially expensive routing features

Die folgende Liste gibt einen Einblick in Routingfeatures, die im Vergleich zu einfachen Routenvorlagen relativ teuer sind:The following list provides some insight into routing features that are relatively expensive compared with basic route templates:

  • Reguläre Ausdrücke: Mit einer kleinen Menge an Eingaben ist möglich, reguläre Ausdrücke zu schreiben, die komplex sind oder eine lange Ausführungszeit haben.Regular expressions: It's possible to write regular expressions that are complex, or have long running time with a small amount of input.

  • Komplexe Segmente ({x}-{y}-{z}):Complex segments ({x}-{y}-{z}):

    • Sind wesentlich teurer als das Analysieren eines regulären URL-Pfadsegments.Are significantly more expensive than parsing a regular URL path segment.
    • Führen dazu, dass viel mehr Teilzeichenfolgen zugeordnet werden.Result in many more substrings being allocated.
    • Die komplexe Segmentlogik wurde beim Aktualisieren der ASP.NET Core 3.0-Routingleistung nicht aktualisiert.The complex segment logic was not updated in ASP.NET Core 3.0 routing performance update.
  • Synchroner Datenzugriff: Viele komplexe Apps verfügen im Rahmen Ihrer Routingfunktionen über Datenbankzugriff.Synchronous data access: Many complex apps have database access as part of their routing. Das Routing in ASP.NET Core 2.2 und früheren Versionen bietet möglicherweise nicht die richtigen Erweiterungspunkte zur Unterstützung des Routings für den Datenbankzugriff.ASP.NET Core 2.2 and earlier routing might not provide the right extensibility points to support database access routing. Zum Beispiel sind IRouteConstraint und IActionConstraint synchron.For example, IRouteConstraint, and IActionConstraint are synchronous. Erweiterbarkeitspunkte wie MatcherPolicy und EndpointSelectorContext sind asynchron.Extensibility points such as MatcherPolicy and EndpointSelectorContext are asynchronous.

Leitfaden für BibliotheksautorenGuidance for library authors

Dieser Abschnitt enthält Hinweise für Bibliotheksautoren, die auf dem Routing aufbauen.This section contains guidance for library authors building on top of routing. Diese Details sollen sicherstellen, dass App-Entwickler gute Erfahrungen mit Bibliotheken und Frameworks machen, die das Routing erweitern.These details are intended to ensure that app developers have a good experience using libraries and frameworks that extend routing.

Definieren von EndpunktenDefine endpoints

Wenn Sie ein Framework erstellen möchten, das das Routing für den URL-Abgleich verwendet, sollten Sie zunächst eine Benutzeroberfläche definieren, die auf UseEndpoints aufbaut.To create a framework that uses routing for URL matching, start by defining a user experience that builds on top of UseEndpoints.

Es wird empfohlen, dass Sie auf IEndpointRouteBuilder aufbauen.DO build on top of IEndpointRouteBuilder. Auf diese Weise können Benutzer Ihr Framework mit anderen ASP.NET Core-Features problemlos zusammenstellen.This allows users to compose your framework with other ASP.NET Core features without confusion. Jede ASP.NET Core-Vorlage umfasst die Routingfunktionalität.Every ASP.NET Core template includes routing. Gehen Sie davon aus, dass das Routing vorhanden und den Benutzern vertraut ist.Assume routing is present and familiar for users.

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

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

Es wird empfohlen, dass Sie einen versiegelten konkreten Typ aus einem Aufruf an MapMyFramework(...) zurückgeben, der IEndpointConventionBuilder implementiert.DO return a sealed concrete type from a call to MapMyFramework(...) that implements IEndpointConventionBuilder. Die meisten Map...-Methoden in Frameworks folgen diesem Muster.Most framework Map... methods follow this pattern. Die IEndpointConventionBuilder-Schnittstelle:The IEndpointConventionBuilder interface:

  • Ermöglicht die Kombinierbarkeit von Metadaten.Allows composability of metadata.
  • Wird von verschiedenen Erweiterungsmethoden angesteuert.Is targeted by a variety of extension methods.

Wenn Sie Ihren eigenen Typ deklarieren, können Sie dem Generator Ihre eigene frameworkspezifische Funktionalität hinzufügen.Declaring your own type allows you to add your own framework-specific functionality to the builder. Es ist in Ordnung, einen vom Framework deklarierten Generator zu umschließen und Aufrufe an ihn weiterzuleiten.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");
});

Ziehen Sie in Betracht, Ihre eigene EndpointDataSource-Klasse zu schreiben.CONSIDER writing your own EndpointDataSource. Die EndpointDataSource-Klasse vom primitiven Typ auf niedriger Ebene eignet sich zum Deklarieren und Aktualisieren einer Sammlung von Endpunkten.EndpointDataSource is the low-level primitive for declaring and updating a collection of endpoints. EndpointDataSource ist eine leistungsstarke API, die von Controllern und Razor Pages verwendet wird.EndpointDataSource is a powerful API used by controllers and Razor Pages.

Die Routingtests haben ein grundlegendes Beispiel für eine Datenquelle, die nicht aktualisiert wird.The routing tests have a basic example of a non-updating data source.

Versuchen Sie nicht, eine EndpointDataSource-Klasse standardmäßig zu registrieren.DO NOT attempt to register an EndpointDataSource by default. Fordern Sie die Benutzer auf, Ihr Framework in UseEndpoints zu registrieren.Require users to register your framework in UseEndpoints. Der Grundgedanke beim Routing ist, dass standardmäßig nichts enthalten ist, und dass die Endpunkte bei UseEndpoints registriert werden müssen.The philosophy of routing is that nothing is included by default, and that UseEndpoints is the place to register endpoints.

Erstellen von in das Routing integrierter MiddlewareCreating routing-integrated middleware

Ziehen Sie in Betracht, Metadatentypen als Schnittstelle zu definieren.CONSIDER defining metadata types as an interface.

Ermöglichen Sie, Metadatentypen als Attribut für Klassen und Methoden zu verwenden.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;
}

Frameworks wie Controller und Razor Pages unterstützen die Anwendung von Metadatenattributen auf Typen und Methoden.Frameworks like controllers and Razor Pages support applying metadata attributes to types and methods. Für das Deklarieren von Metadatentypen gilt:If you declare metadata types:

  • Machen Sie diese als Attribute zugänglich.Make them accessible as attributes.
  • Die meisten Benutzer sind mit der Anwendung von Attributen vertraut.Most users are familiar with applying attributes.

Durch die Deklaration eines Metadatentyps als Schnittstelle wird die Flexibilität zusätzlich erhöht:Declaring a metadata type as an interface adds another layer of flexibility:

  • Schnittstelle können zusammengesetzt werden.Interfaces are composable.
  • Entwickler können ihre eigenen Typen deklarieren, die mehrere Richtlinien kombinieren.Developers can declare their own types that combine multiple policies.

Ermöglichen Sie, Metadaten außer Kraft zu setzen, wie in folgendem Beispiel gezeigt: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() { }
}

Die beste Möglichkeit, diese Richtlinien zu befolgen, besteht darin, die Definition von Markermetadaten zu vermeiden:The best way to follow these guidelines is to avoid defining marker metadata:

  • Suchen Sie nicht nur nach dem Vorhandensein eines Metadatentyps.Don't just look for the presence of a metadata type.
  • Definieren Sie eine Eigenschaft für die Metadaten, und überprüfen Sie die Eigenschaft.Define a property on the metadata and check the property.

Die Metadatensammlung ist geordnet und unterstützt das Außerkraftsetzen nach Priorität.The metadata collection is ordered and supports overriding by priority. Im Fall von Controllern sind Metadaten für die Aktionsmethode am spezifischsten.In the case of controllers, metadata on the action method is most specific.

Nutzen Sie Middleware mit und ohne Routing.DO make middleware useful with and without routing.

app.UseRouting();

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

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

Ein gutes Beispiel für diese Vorgabe ist die UseAuthorization-Middleware.As an example of this guideline, consider the UseAuthorization middleware. Mithilfe der Autorisierungsmiddleware können Sie eine Fallbackrichtlinie einbauen.The authorization middleware allows you to pass in a fallback policy. Die Fallbackrichtlinie gilt, falls angegeben, für beide:The fallback policy, if specified, applies to both:

  • Endpunkte ohne angegebene Richtlinie.Endpoints without a specified policy.
  • Anforderungen, die nicht mit einem Endpunkt übereinstimmen.Requests that don't match an endpoint.

Dies macht die Autorisierungsmiddleware außerhalb des Routingkontexts sehr nützlich.This makes the authorization middleware useful outside of the context of routing. Die Autorisierungsmiddleware kann für die traditionelle Middlewareprogrammierung verwendet werden.The authorization middleware can be used for traditional middleware programming.

DebugdiagnoseDebug diagnostics

Legen Sie für eine ausführliche Routingdiagnoseausgabe Logging:LogLevel:Microsoft auf Debug fest.For detailed routing diagnostic output, set Logging:LogLevel:Microsoft to Debug. Legen Sie in der Entwicklungsumgebung die Protokollebene in appsettings.Development.jsauffest:In the development environment, set the log level in appsettings.Development.json:

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

Beim Routing werden Anforderungs-URIs Endpunkten zugeordnet und Anforderungen an diese Endpunkte weitergeleitet.Routing is responsible for mapping request URIs to endpoints and dispatching incoming requests to those endpoints. Routen werden in der App definiert und beim Start der App konfiguriert.Routes are defined in the app and configured when the app starts. Eine Route kann optional Werte aus der URL extrahieren, die in der Anforderung enthalten ist. Diese Werte können anschließend für die Verarbeitung der Anforderung verwendet werden.A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. Mithilfe von Routeninformationen aus der App lassen sich durch das Routing URLs generieren, die Endpunkten zugeordnet werden.Using route information from the app, routing is also able to generate URLs that map to endpoints.

Wenn Sie die aktuellsten Routingszenarios in ASP.NET Core 2.2 verwenden möchten, geben Sie die Kompatibilitätsversion zur Registrierung der MVC-Dienste in Startup.ConfigureServices an: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);

Die Option EnableEndpointRouting bestimmt, ob für das Routing intern endpunktbasierte Logik oder IRouter-basierte Logik von ASP.NET Core 2.1 oder früher verwendet werden soll.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. Wenn die Kompatibilitätsversion auf 2.2 oder höher festgelegt ist, lautet der Standardwert true.When the compatibility version is set to 2.2 or later, the default value is true. Legen Sie für den Wert false fest, um die vorherige Routinglogik zu verwenden: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);

Weitere Informationen zum IRouter-basierten Routing finden Sie in dem Artikel zur Version 2.1 von ASP.NET Core.For more information on IRouter-based routing, see the ASP.NET Core 2.1 version of this topic.

Wichtig

In diesem Artikel wird das Low-Level-Routing in ASP.NET Core beschrieben.This document covers low-level ASP.NET Core routing. Weitere Informationen zum Routing mit ASP.NET Core MVC finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.For information on ASP.NET Core MVC routing, see Routing zu Controlleraktionen in ASP.NET Core. Weitere Informationen zu Routingkonventionen in Razor Pages finden Sie unter Razor Pages: Routen- und App-Konventionen in ASP.NET Core.For information on routing conventions in Razor Pages, see Razor Pages: Routen- und App-Konventionen in ASP.NET Core.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

RoutinggrundlagenRouting basics

Für die meisten Apps sollte eine grundlegendes und beschreibendes Routingschema ausgewählt werden, um lesbare und aussagekräftige URLs zu erhalten.Most apps should choose a basic and descriptive routing scheme so that URLs are readable and meaningful. Für die konventionelle Standardroute {controller=Home}/{action=Index}/{id?} gilt:The default conventional route {controller=Home}/{action=Index}/{id?}:

  • Sie unterstützt ein grundlegendes und beschreibendes Routingschema.Supports a basic and descriptive routing scheme.
  • Sie stellt einen nützlichen Startpunkt für benutzeroberflächenbasierte Apps dar.Is a useful starting point for UI-based apps.

Entwickler fügen in der Regel in speziellen Situationen durch Attributrouting oder dedizierte konventionelle Routen zusätzliche kurze Routen zu stark frequentierten Bereichen der App hinzu.Developers commonly add additional terse routes to high-traffic areas of an app in specialized situations using attribute routing or dedicated conventional routes. Beispiele für spezielle Situationen sind unter anderem Blog- und E-Commerce-Endpunkte.Specialized situations examples include, blog and ecommerce endpoints.

Web-APIs sollten das Attributrouting verwenden, um die Funktionalität der App als einen Satz von Ressourcen zu modellieren, bei denen Vorgänge durch HTTP-Verben dargestellt werden.Web APIs should use attribute routing to model the app's functionality as a set of resources where operations are represented by HTTP verbs. Dies bedeutet, dass viele Vorgänge, z. B. GET und POST, für dieselbe logische Ressource dieselbe URL verwenden.This means that many operations, for example, GET, and POST, on the same logical resource use the same URL. Das Attributrouting bietet eine Ebene der Steuerung, die für einen sorgfältigen Entwurf des öffentlichen Endpunktlayouts einer API erforderlich ist.Attribute routing provides a level of control that's needed to carefully design an API's public endpoint layout.

Razor Pages-Apps verwenden konventionelles Standardrouting, um benannte Ressourcen im Pages-Ordner einer App bereitzustellen.Razor Pages apps use default conventional routing to serve named resources in the Pages folder of an app. Außerdem gibt es weitere Konventionen zum Anpassen des Routingverhaltens für Razor Pages.Additional conventions are available that allow you to customize Razor Pages routing behavior. Weitere Informationen finden Sie unter Einführung in Razor Pages in ASP.NET Core und Razor Pages: Routen- und App-Konventionen in ASP.NET Core.For more information, see Einführung in Razor Pages in ASP.NET Core and Razor Pages: Routen- und App-Konventionen in ASP.NET Core.

Die Unterstützung zum Generieren von URLs ermöglicht es, die App ohne Hartcodierung der URLs zum Verlinken der App zu entwickeln.URL generation support allows the app to be developed without hard-coding URLs to link the app together. Auf diese Weise kann mit einer grundlegenden Routingkonfiguration begonnen werden, und die Routen können geändert werden, wenn das Ressourcenlayout der App festgelegt wurde.This support allows for starting with a basic routing configuration and modifying the routes after the app's resource layout is determined.

Es werden Endpunkte (Endpoint) für das Routing verwendet, um logische Endpunkte in einer App darzustellen.Routing uses endpoints (Endpoint) to represent logical endpoints in an app.

Ein Endpunkt definiert einen Delegaten zum Verarbeiten von Anforderungen und eine Sammlung von beliebigen Metadaten.An endpoint defines a delegate to process requests and a collection of arbitrary metadata. Die Metadaten werden zur Implementierung von übergreifenden Belangen verwendet, die auf Richtlinien und der Konfiguration basieren, die den einzelnen Endpunkten angefügt sind.The metadata is used implement cross-cutting concerns based on policies and configuration attached to each endpoint.

Das Routingsystem weist die folgenden Eigenschaften auf:The routing system has the following characteristics:

  • Die Syntax der Routenvorlage wird zum Definieren von Routen mit Routenparametern verwendet, die mit Token versehen sind.Route template syntax is used to define routes with tokenized route parameters.

  • Sowohl die konventionelle Endpunktkonfiguration als auch die Endpunktkonfiguration mit Attributen ist zulässig.Conventional-style and attribute-style endpoint configuration is permitted.

  • IRouteConstraint wird verwendet, um zu bestimmen, ob ein URL-Parameter einen gültigen Wert für eine bestimmte Endpunkteinschränkung enthält.IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.

  • App-Modelle wie MVC bzw. Razor Pages registrieren sämtliche Endpunkte, für die die Implementierung von Routingszenarios vorhersagbar ist.App models, such as MVC/Razor Pages, register all of their endpoints, which have a predictable implementation of routing scenarios.

  • Die Routingimplementierung trifft Routingentscheidungen, wenn diese in der Middlewarepipeline gewünscht sind.The routing implementation makes routing decisions wherever desired in the middleware pipeline.

  • Middleware, die nach Routingmiddleware angezeigt wird, kann das Ergebnis der Endpunktentscheidung der Routingmiddleware untersuchen, die für einen bestimmten Anforderungs-URI getroffen wurde.Middleware that appears after a Routing Middleware can inspect the result of the Routing Middleware's endpoint decision for a given request URI.

  • Alle diese Endpunkte können an einer beliebigen Stelle in der Middlewarepipeline in der App aufgelistet werden.It's possible to enumerate all of the endpoints in the app anywhere in the middleware pipeline.

  • Apps können mithilfe von Routing URLs generieren (z. B. für Umleitungen oder Links), die auf Endpunktinformationen basieren. Dadurch wird die Erstellung von hartcodierten URLs verhindert, was wiederrum die Wartbarkeit verbessert.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.

  • Die URL-Generierung basiert auf Adressen, die beliebige Erweiterbarkeit unterstützen:URL generation is based on addresses, which support arbitrary extensibility:

    • Die API zur Linkgenerierung (LinkGenerator) kann mithilfe von Dependency Injection an jeder beliebigen Stelle aufgelöst werden, um URLs zu generieren.The Link Generator API (LinkGenerator) can be resolved anywhere using dependency injection (DI) to generate URLs.
    • Wenn diese API nicht über Dependency Injection verfügbar ist, bietet IUrlHelper Methoden zum Erstellen von URLs.Where the Link Generator API isn't available via DI, IUrlHelper offers methods to build URLs.

Hinweis

Mit der Freigabe des Endpunktroutings in ASP.NET Core 2.2 wird die Endpunktverknüpfung auf MVC- bzw. Razor Pages-Aktionen und -Seiten eingeschränkt.With the release of endpoint routing in ASP.NET Core 2.2, endpoint linking is limited to MVC/Razor Pages actions and pages. Zukünftige Releases sollen Erweiterungen für Funktionen zur Verknüpfung von Endpunkten enthalten.The expansions of endpoint-linking capabilities is planned for future releases.

Die Routingfunktionalität wird über die Klasse RouterMiddleware mit der Middlewarepipeline verbunden.Routing is connected to the middleware pipeline by the RouterMiddleware class. ASP.NET Core-MVC fügt im Rahmen der Konfiguration die Routingfunktionalität der Middlewarepipeline hinzu und verarbeitet das Routing in MVC- und Razor Pages-Apps.ASP.NET Core MVC adds routing to the middleware pipeline as part of its configuration and handles routing in MVC and Razor Pages apps. Informationen darüber, wie Sie Routing als eigenständige Komponente verwenden, finden Sie im Abschnitt Verwenden von Routingmiddleware.To learn how to use routing as a standalone component, see the Use Routing Middleware section.

URL-ZuordnungURL matching

Bei einer URL-Zuordnung werden eingehende Anforderungen durch Routing an einen Endpunkt gesendet.URL matching is the process by which routing dispatches an incoming request to an endpoint. Für diesen Prozess werden die Daten des URL-Pfads verwendet. Es können jedoch auch alle Daten der Anforderung genutzt werden.This process is based on data in the URL path but can be extended to consider any data in the request. Für die Skalierung der Größe und Komplexität einer App ist das Versenden von Anforderungen an unterschiedliche Handler entscheidend.The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

Das Routingsystem ist beim Endpunktrouting für alle Weiterleitungsentscheidungen zuständig.The routing system in endpoint routing is responsible for all dispatching decisions. Da die Middleware basierend auf dem ausgewählten Endpunkt Richtlinien anwendet, ist es wichtig, dass jede Entscheidung, die die Weiterleitung oder die Anwendung von Sicherheitsrichtlinien beeinträchtigen kann, innerhalb des Routingsystems getroffen wird.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.

Wenn der Endpunktdelegat ausgeführt wird, werden die Eigenschaften von RouteContext.RouteData auf Grundlage der bisher verarbeiteten Anforderungen auf entsprechende Werte festgelegt.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 ist ein Wörterbuch mit Routenwerten, das aus der Route erstellt wird.RouteData.Values is a dictionary of route values produced from the route. Die Werte werden in der Regel durch die Tokenisierung der URL ermittelt und können so verwendet werden, dass Benutzereingaben akzeptiert oder weitere Entscheidungen in der App zum Versenden von Anforderungen getroffen werden.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 ist eine Eigenschaftensammlung mit zusätzlichen Daten zur zugeordneten Route.RouteData.DataTokens is a property bag of additional data related to the matched route. DataTokens werden bereitgestellt, damit sich jeder Route Zustandsdaten zuordnen lassen, sodass in der App später Entscheidungen auf Grundlage der zugeordneten Route getroffen werden können.DataTokens are provided to support associating state data with each route so that the app can make decisions based on which route matched. Diese Werte werden vom Entwickler vorgegeben und beeinflussen das Routingverhalten in keiner Weise.These values are developer-defined and do not affect the behavior of routing in any way. Außerdem können im Gegensatz zu RouteData.Values, die sich in bzw. aus Zeichenfolgen konvertieren lassen müssen, Werte in RouteData.DataTokens einem beliebigen Typ entsprechen.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 ist eine Liste der Routen, die an der Zuordnung der Anforderung beteiligt waren.RouteData.Routers is a list of the routes that took part in successfully matching the request. Routen können in anderen Routen geschachtelt werden.Routes can be nested inside of one another. Die Routers-Eigenschaft stellt den Pfad mithilfe der logischen Routenstruktur dar, die zu der Zuordnung geführt hat.The Routers property reflects the path through the logical tree of routes that resulted in a match. Üblicherweise ist das erste Element in Routers die Routensammlung. Dieses sollte zur URL-Generierung verwendet werden.Generally, the first item in Routers is the route collection and should be used for URL generation. Das letzte Element in Routers ist der Routenhandler, für den eine Zuordnung vorgenommen wurde.The last item in Routers is the route handler that matched.

URL-Generierung mit LinkGeneratorURL generation with LinkGenerator

Bei der URL-Generierung wird durch Routing ein URL-Pfad basierend auf mehreren Routenwerten erstellt.URL generation is the process by which routing can create a URL path based on a set of route values. Dies ermöglicht eine logische Trennung zwischen den Endpunkten und den URLs, die auf diese zugreifen.This allows for a logical separation between your endpoints and the URLs that access them.

Das Endpunktrouting umfasst die API zur Linkgenerierung (LinkGenerator).Endpoint routing includes the Link Generator API (LinkGenerator). LinkGenerator ist ein Singletondienst, der über DI abgerufen werden kann.LinkGenerator is a singleton service that can be retrieved from DI. Die API kann außerhalb des Kontexts einer ausgeführten Anforderung verwendet werden.The API can be used outside of the context of an executing request. IUrlHelper und Szenarios für MVC, die von IUrlHelper abhängig sind (z. B. Taghilfsprogramme, HTML-Hilfsprogramme und Aktionsergebnisse), verwenden die API zur Linkgenerierung, um entsprechende Funktionen bereitzustellen.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.

Die API zur Linkgenerierung wird von Konzepten wie Adressen und Adressschemas unterstützt.The link generator is backed by the concept of an address and address schemes. Sie können mithilfe eines Adressschemas die Endpunkte bestimmen, die bei der Linkgenerierung berücksichtigt werden sollen.An address scheme is a way of determining the endpoints that should be considered for link generation. Beispielsweise werden Routennamen und Routenwerte als Adressschemas implementiert. Diese Szenarios kennen viele Benutzer von MVC bzw. Razor Pages.For example, the route name and route values scenarios many users are familiar with from MVC/Razor Pages are implemented as an address scheme.

Die API zur Linkgenerierung kann MVC- bzw. Razor Pages-Aktionen und Seiten über die folgenden Erweiterungsmethoden miteinander verknüpfen:The link generator can link to MVC/Razor Pages actions and pages via the following extension methods:

Beim Überladen dieser Methoden werden Argumente akzeptiert, die den HttpContext umfassen.An overload of these methods accepts arguments that include the HttpContext. Diese Methoden sind zwar in funktionaler Hinsicht äquivalent zu Url.Action und Url.Page, bieten aber zusätzliche Flexibilität und Optionen.These methods are functionally equivalent to Url.Action and Url.Page but offer additional flexibility and options.

Die GetPath*-Methoden sind Url.Action und Url.Page in der Hinsicht ähnlich, dass sie einen URI mit einem absoluten Pfad generieren.The GetPath* methods are most similar to Url.Action and Url.Page in that they generate a URI containing an absolute path. Die GetUri*-Methoden generieren immer einen absoluten URI mit einem Schema und einem Host.The GetUri* methods always generate an absolute URI containing a scheme and host. Die Methoden, die einen HttpContext akzeptieren, generieren im Kontext der ausgeführten Anforderung einen URI.The methods that accept an HttpContext generate a URI in the context of the executing request. Die Umgebungsroutenwerte, der URL-basierte Pfad, das Schema und der Host von der ausführenden Anforderung werden so lange verwendet, bis sie außer Kraft gesetzt werden.The ambient route values, URL base path, scheme, and host from the executing request are used unless overridden.

LinkGenerator wird mit einer Adresse aufgerufen.LinkGenerator is called with an address. Ein URI wird in zwei Schritten generiert:Generating a URI occurs in two steps:

  1. Eine Adresse wird an eine Liste von Endpunkten gebunden, die der Adresse zugeordnet werden können.An address is bound to a list of endpoints that match the address.
  2. Jedes RoutePattern eines Endpunkts wird bewertet, bis ein Routenmuster gefunden wird, das den angegebenen Werten zugeordnet werden kann.Each endpoint's RoutePattern is evaluated until a route pattern that matches the supplied values is found. Die daraus resultierende Ausgabe wird mit URI-Teilen kombiniert, die für die API zur Linkgenerierung bereitgestellt wird, und zurückgegeben.The resulting output is combined with the other URI parts supplied to the link generator and returned.

Die von LinkGenerator bereitgestellten Methoden unterstützen die Standardfunktionen zur Generierung von Links für jeden beliebigen Adresstypen.The methods provided by LinkGenerator support standard link generation capabilities for any type of address. Am praktischsten ist es, die API zur Linkgenerierung mit Erweiterungsmethoden zu verwenden, die Vorgänge für einen bestimmten Adresstypen ausführen.The most convenient way to use the link generator is through extension methods that perform operations for a specific address type.

ErweiterungsmethodeExtension Method BeschreibungDescription
GetPathByAddress Generiert einen URI mit einem absoluten Pfad, der auf den angegebenen Werten basiert.Generates a URI with an absolute path based on the provided values.
GetUriByAddress Generiert einen absoluten URI, der auf den angegebenen Werten basiert.Generates an absolute URI based on the provided values.

Warnung

Beachten Sie die folgenden Implikationen zum Aufrufen von LinkGenerator-Methoden:Pay attention to the following implications of calling LinkGenerator methods:

  • Verwenden Sie GetUri*-Erweiterungsmethoden in App-Konfigurationen, die den Host-Header von eingehenden Anforderungen nicht überprüfen, mit Bedacht.Use GetUri* extension methods with caution in an app configuration that doesn't validate the Host header of incoming requests. Wenn der Host-Header von eingehenden Anforderungen nicht überprüft wird, können nicht vertrauenswürdige Anforderungseingaben zurück an den Client in URIs einer Ansicht bzw. Seite zurückgesendet werden.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. Es wird empfohlen, dass alle Produktions-Apps ihren Server so konfigurieren, dass der Host-Header auf bekannte gültige Werte überprüft wird.We recommend that all production apps configure their server to validate the Host header against known valid values.

  • Verwenden Sie LinkGenerator in Kombination mit Map oder MapWhen in Middleware mit Bedacht.Use LinkGenerator with caution in middleware in combination with Map or MapWhen. Map* ändert den Basispfad der ausgeführten Anforderung. Dies beeinflusst die Ausgabe der Linkgenerierung.Map* changes the base path of the executing request, which affects the output of link generation. Für alle LinkGenerator-APIs ist die Angabe eines Basispfads zulässig.All of the LinkGenerator APIs allow specifying a base path. Geben Sie immer einen leeren Basispfad an, um den Einfluss von Map* auf die Linkgenerierung rückgängig zu machen.Always specify an empty base path to undo Map*'s affect on link generation.

Unterschiede im Vergleich zu früheren RoutingversionenDifferences from earlier versions of routing

Es gibt einige Unterschiede zwischen dem Endpunktrouting in ASP.NET Core 2.2 oder höher und dem Routing in früheren Versionen von 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:

  • Das Endpunktroutingsystem unterstützt die IRouter-basierte Erweiterbarkeit einschließlich des Erbens von Route nicht.The endpoint routing system doesn't support IRouter-based extensibility, including inheriting from Route.

  • Das Endpunktrouting unterstützt WebApiCompatShim nicht.Endpoint routing doesn't support WebApiCompatShim. Verwenden Sie die Kompatibilitätsversion für 2.1 (.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)), um den Kompatibilitätsshim weiter zu verwenden.Use the 2.1 compatibility version (.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)) to continue using the compatibility shim.

  • Das Verhalten des Endpunktroutings für die Schreibweise von generierten URIs ist bei der Verwendung von konventionellen Routen anders.Endpoint Routing has different behavior for the casing of generated URIs when using conventional routes.

    Sehen Sie sich die folgende Standardvorlage für Routen an:Consider the following default route template:

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

    Angenommen, Sie generieren mithilfe der folgenden Route einen Link zu einer Aktion:Suppose you generate a link to an action using the following route:

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

    Bei IRouter-basierten Routing generiert dieser Code einen URI von /blog/ReadPost/17, der die Schreibweise des angegebenen Routenwerts berücksichtigt.With IRouter-based routing, this code generates a URI of /blog/ReadPost/17, which respects the casing of the provided route value. Durch das Endpunktrouting in ASP.NET Core 2.2 oder höher wird /Blog/ReadPost/17 hergestellt („Blog“ wird großgeschrieben).Endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 ("Blog" is capitalized). Über das Endpunktrouting wird die IOutboundParameterTransformer-Schnittstelle bereitgestellt, die verwendet werden kann, um dieses Verhalten entweder global anzupassen oder auf unterschiedliche Konventionen zum Zuordnen von URLs anzuwenden.Endpoint routing provides the IOutboundParameterTransformer interface that can be used to customize this behavior globally or to apply different conventions for mapping URLs.

    Weitere Informationen finden Sie im Abschnitt Parametertransformatorreferenz.For more information, see the Parameter transformer reference section.

  • Das Verhalten der von MVC bzw. Razor Pages mit konventionellen Routen verwendeten Linkgenerierung unterscheidet sich, wenn versucht wird, einen Controller bzw. eine Aktion oder Seite zu verknüpfen, die nicht vorhanden ist.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.

    Sehen Sie sich die folgende Standardvorlage für Routen an:Consider the following default route template:

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

    Angenommen, Sie generieren mithilfe der Standardvorlage wie folgt einen Link zu einer Aktion:Suppose you generate a link to an action using the default template with the following:

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

    Bei IRouter-basiertem Routing ist das Ergebnis immer /Blog/ReadPost/17, auch wenn BlogController nicht vorhanden ist oder keine Aktionsmethode für ReadPost aufweist.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. Erwartungsgemäß wird durch das Endpunktrouting in ASP.NET Core 2.2 oder höher /Blog/ReadPost/17 erstellt, wenn die Aktionsmethode vorhanden ist.As expected, endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 if the action method exists. Wenn die Aktionsmethode allerdings nicht vorhanden ist, wird beim Endpunktrouting eine leere Zeichenfolge erstellt.However, endpoint routing produces an empty string if the action doesn't exist. Vom Konzept her wird beim Endpunktrouting nicht angenommen, dass der Endpunkt vorhanden ist, wenn es die Aktion nicht gibt.Conceptually, endpoint routing doesn't assume that the endpoint exists if the action doesn't exist.

  • Das Verhalten des Algorithmus zum Aufheben der Gültigkeit von Umgebunsgwerten bei der Linkgenerierung ist anders, wenn dieser im Zusammenhang mit dem Endpunktrouting verwendet wird.The link generation ambient value invalidation algorithm behaves differently when used with endpoint routing.

    Anhand des Algorithmus zum Aufheben der Gültigkeit von Umgebungswerten wird entschieden, welche Routenwerte der zu diesem Zeitpunkt ausgeführten Anforderung (die Umgebunsgwerte) für die Linkgenerierung verwendet werden können.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. Beim konventionellen Routing wurde stets die Gültigkeit von zusätzlichen Routenwerten aufgehoben, wenn eine Verknüpfung zu einer anderen Aktion hergestellt wurde.Conventional routing always invalidated extra route values when linking to a different action. Beim Attributrouting ist dieses Verhalten vor dem Release von ASP.NET Core 2.2 nicht aufgetreten.Attribute routing didn't have this behavior prior to the release of ASP.NET Core 2.2. In früheren Versionen von ASP.NET Core wurden beim Herstellen von Verknüpfungen mit einer anderen Aktion, die dieselben Namen für Routenparameter verwendete, ein Fehler bei der Linkgenerierung ausgelöst.In earlier versions of ASP.NET Core, links to another action that use the same route parameter names resulted in link generation errors. In ASP.NET Core 2.2 oder höher wird bei beiden Arten des Routings die Gültigkeit von Werten aufgehoben, wenn eine Verknüpfung zu einer anderen Aktion hergestellt wird.In ASP.NET Core 2.2 or later, both forms of routing invalidate values when linking to another action.

    Sehen Sie sich das folgende Beispiel in ASP.NET Core 2.1 oder früher an.Consider the following example in ASP.NET Core 2.1 or earlier. Wenn eine Verknüpfung zu einer anderen Aktion (oder Seite) hergestellt wird, können Routenwerte auf unerwünschte Weise wiederverwendet werden.When linking to another action (or another page), route values can be reused in undesirable ways.

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

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

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

    @page "{id?}"
    

    Wenn der URI in ASP.NET Core 2.1 oder früher /Store/Product/18 ist, ist der Link, der von @Url.Page("/Login") auf der Speicher- bzw. Informationsseite generiert wird, /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. Der id-Wert von 18 wird wiederverwendet, obwohl das Ziel des Links ein vollkommen anderer Teil der App ist.The id value of 18 is reused, even though the link destination is different part of the app entirely. Bei dem id-Routenwert im Kontext der /Login-Seite handelt es sich wahrscheinlich um den Wert einer Benutzer-ID und nicht um einen Wert einer Speicherprodukt-ID.The id route value in the context of the /Login page is probably a user ID value, not a store product ID value.

    Beim Endpunktrouting mit ASP.NET Core 2.2 oder höher lautet das Ergebnis /Login.In endpoint routing with ASP.NET Core 2.2 or later, the result is /Login. Umgebungswerte werden nicht wiederverwendet, wenn das verknüpfte Ziel eine andere Aktion oder Seite ist.Ambient values aren't reused when the linked destination is a different action or page.

  • Syntax für Routenparameter für Roundtrips: Schrägstriche werden nicht codiert, wenn eine Syntax mit zwei Sternchen (**) für Catch-All-Parameter verwendet wird.Round-tripping route parameter syntax: Forward slashes aren't encoded when using a double-asterisk (**) catch-all parameter syntax.

    Bei der Linkgenerierung codiert das Routingsystem mit Ausnahme von Schrägstrichen den Wert in einem Catch-All-Parameter, dem zwei Sternchen voranstehen (**), z. B. {**myparametername}.During link generation, the routing system encodes the value captured in a double-asterisk (**) catch-all parameter (for example, {**myparametername}) except the forward slashes. Der Catch-All-Parameter mit zwei Sternchen wird beim IRouter-basierten Routing in ASP.NET Core 2.2 oder höher unterstützt.The double-asterisk catch-all is supported with IRouter-based routing in ASP.NET Core 2.2 or later.

    Die Syntax mit einem Sternchen für Catch-All-Parameter in früheren Versionen von ASP.NET Core ({*myparametername}) wird weiter unterstützt, und Schrägstriche werden codiert.The single asterisk catch-all parameter syntax in prior versions of ASP.NET Core ({*myparametername}) remains supported, and forward slashes are encoded.

    RouteRoute Link generiert mit:Link generated with
    Url.Action(new { category = "admin/products" })
    /search/{*page} /search/admin%2Fproducts (der Schrägstrich wird codiert)/search/admin%2Fproducts (the forward slash is encoded)
    /search/{**page} /search/admin/products

MiddlewarebeispielMiddleware example

Im folgenden Beispiel verwendet eine Middleware die LinkGenerator-API, um eine Verknüpfung zu einer Aktionsmethode herzustellen, die Speicherprodukte aufführt.In the following example, a middleware uses the LinkGenerator API to create link to an action method that lists store products. Sie können für jede beliebige Klasse in einer App die API zur Linkgenerierung verwenden, indem Sie diese in eine Klasse einfügen und GenerateLink aufrufen.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.");
    }
}

Erstellen von RoutenCreate routes

Die meisten Apps erstellen Routen, indem sie MapRoute oder eine ähnliche Erweiterungsmethode aufrufen, die in IRouteBuilder definiert ist.Most apps create routes by calling MapRoute or one of the similar extension methods defined on IRouteBuilder. All diese IRouteBuilder-Erweiterungsmethoden erstellen eine Instanz von Route und fügen diese der Routensammlung hinzu.Any of the IRouteBuilder extension methods create an instance of Route and add it to the route collection.

MapRoute akzeptiert keine Routenhandlerparameter.MapRoute doesn't accept a route handler parameter. Durch MapRoute werden nur Routen hinzugefügt, die vom DefaultHandler verarbeitet werden.MapRoute only adds routes that are handled by the DefaultHandler. Weitere Informationen zum Routing in MVC finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.To learn more about routing in MVC, see Routing zu Controlleraktionen in ASP.NET Core.

Im folgenden Codebeispiel wird ein MapRoute-Aufruf dargestellt, der von einer typischen ASP.NET Core MVC-Routendefinition verwendet wird: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?}");

Diese Vorlage ordnet einen URL-Pfad zu und extrahiert die Routenwerte.This template matches a URL path and extracts the route values. Beispielsweise generiert der Pfad /Products/Details/17 die folgenden Routenwerte: { controller = Products, action = Details, id = 17 }.For example, the path /Products/Details/17 generates the following route values: { controller = Products, action = Details, id = 17 }.

Routenwerte werden ermittelt, indem der URL-Pfad in Segmente aufgeteilt wird und jedes Segment mit dem Namen des Routenparameters in der Routenvorlage abgeglichen wird.Route values are determined by splitting the URL path into segments and matching each segment with the route parameter name in the route template. Jeder Routenparameter hat einen Namen.Route parameters are named. Die Parameter werden von Klammern { ... } eingeschlossen und dadurch definiert.The parameters defined by enclosing the parameter name in braces { ... }.

Die obige Vorlage kann auch dem URL-Pfad / zugeordnet werden und daraus die Werte { controller = Home, action = Index } generieren.The preceding template could also match the URL path / and produce the values { controller = Home, action = Index }. Dies liegt daran, dass die Routenparameter {controller} und {action} über Standardwerte verfügen und der Routenparameter id optional ist.This occurs because the {controller} and {action} route parameters have default values and the id route parameter is optional. Hinter dem Namen des Routenparameters steht das Gleichheitszeichen (=), auf das der Wert folgt, der als Standardwert für den Parameter definiert wird.An equals sign (=) followed by a value after the route parameter name defines a default value for the parameter. Durch ein Fragezeichen (?) nach dem Namen des Routenparameters wird ein optionaler Parameter definiert.A question mark (?) after the route parameter name defines an optional parameter.

Durch Routenparameter mit einem Standardwert wird immer ein Routenwert erzeugt, wenn eine Übereinstimmung für die Route ermittelt wird.Route parameters with a default value always produce a route value when the route matches. Bei optionalen Parametern wird kein Routenwert generiert, wenn kein entsprechendes URL-Pfadsegment vorhanden ist.Optional parameters don't produce a route value if there is no corresponding URL path segment. Eine ausführliche Beschreibung zu den Szenarios und zur Syntax der Routenvorlage finden Sie unter Referenz zu Routenvorlagen.See the Route template reference section for a thorough description of route template scenarios and syntax.

Im folgenden Beispiel definiert die Routenparameterdefinition {id:int} eine Routeneinschränkung für den Routenparameter 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}");

Durch diese Vorlage wird bei einem Abgleich beispielsweise der URL-Pfad /Products/Details/17, aber nicht /Products/Details/Apples gefunden.This template matches a URL path like /Products/Details/17 but not /Products/Details/Apples. In derartigen Einschränkungen wird IRouteConstraint implementiert, und die Routenwerte werden auf Gültigkeit geprüft.Route constraints implement IRouteConstraint and inspect route values to verify them. Im obigen Beispiel muss sich der Routenwert id in einen Integer konvertieren lassen.In this example, the route value id must be convertible to an integer. Weitere Informationen zu Routeneinschränkungen, die vom Framework bereitgestellt werden, finden Sie in der Referenz zu Routeneinschränkungen.See route-constraint-reference for an explanation of route constraints provided by the framework.

Bei zusätzlichen Überladungen von MapRoute werden Werte für constraints, dataTokens und defaults akzeptiert.Additional overloads of MapRoute accept values for constraints, dataTokens, and defaults. Üblicherweise werden diese Parameter so verwendet, dass ein Objekt eines anonymen Typs übergeben wird, in dem die Eigenschaftsnamen des anonymen Typs mit den Routenparameternamen abgeglichen werden.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.

In den folgenden MapRoute-Beispielen werden identische Routen erstellt: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?}");

Tipp

Für einfache Routen eignet sich die Inline-Syntax zum Definieren von Einschränkungen und Standardwerten.The inline syntax for defining constraints and defaults can be convenient for simple routes. Bestimmte Szenarios wie die Verwendung von Datentoken werden von dieser allerdings nicht unterstützt.However, there are scenarios, such as data tokens, that aren't supported by inline syntax.

Das folgende Beispiel veranschaulicht einige weitere Szenarios:The following example demonstrates a few additional scenarios:

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

Diese Vorlage kann einem URL-Pfad wie /Blog/All-About-Routing/Introduction zugeordnet werden. Sie extrahier die { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }-Werte.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 }. Die Standardroutenwerte für controller und action werden von der Route generiert, obwohl keine entsprechenden Routenparameter in der Vorlage vorhanden sind.The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. Standardwerte können in der Routenvorlage angegeben werden.Default values can be specified in the route template. Der Routenparameter article wird durch zwei Sternchen (**) vor dem zugehörigen Namen als Catch-All-Parameter definiert.The article route parameter is defined as a catch-all by the appearance of an double asterisk (**) before the route parameter name. So wird der verbleibende Teil des URL-Pfads erfasst, und auch leere Zeichenfolgen können gefunden werden.Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

Im folgenden Beispiel werden Routeneinschränkungen und Datentoken hinzugefügt: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" });

Diese Vorlage kann einem URL-Pfad wie /en-US/Products/5 zugeordnet werden, und die { controller = Products, action = Details, id = 5 }-Werte und { locale = en-US }-Datentoken werden extrahiert.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 }.

Gebietsschemas, Windows-Tokens

Generieren der URL zu einer RoutenklasseRoute class URL generation

Durch die Kombination von mehreren Routenwerten und der zugehörigen Routenvorlage kann die Route-Klasse auch URLs generieren.The Route class can also perform URL generation by combining a set of route values with its route template. Dieser Prozess verläuft umgekehrt zum Abgleich eines URL-Pfads.This is logically the reverse process of matching the URL path.

Tipp

Wenn Sie die URL-Generierung besser nachvollziehen möchten, sollten Sie sich überlegen, welche URL generiert werden soll und wie diese mithilfe der Routenvorlage abgeglichen wird.To better understand URL generation, imagine what URL you want to generate and then think about how a route template would match that URL. Dabei sollten Sie auch darüber nachdenken, welche Werte erstellt werden.What values would be produced? Dieser Vorgang entspricht in etwa der URL-Generierung in der Route-Klasse.This is the rough equivalent of how URL generation works in the Route class.

Im folgenden Beispiel wird eine allgemeine Standardroute für ASP.NET Core-MVC verwendet:The following example uses a general ASP.NET Core MVC default route:

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

Mithilfe der Routenwerte { controller = Products, action = List } wird die URL /Products/List generiert.With the route values { controller = Products, action = List }, the URL /Products/List is generated. Die Routenwerte werden als Ersatz für die entsprechenden Routenparameter verwendet, wodurch ein URL-Pfad erstellt werden kann.The route values are substituted for the corresponding route parameters to form the URL path. Da es sich bei id um einen optionalen Routenparameter handelt, wird die URL erfolgreich ohne einen Wert für id generiert.Since id is an optional route parameter, the URL is successfully generated without a value for id.

Mithilfe der Routenwerte { controller = Home, action = Index } wird die URL / generiert.With the route values { controller = Home, action = Index }, the URL / is generated. Die bereitgestellten Routenwerte entsprechen den Standardwerten, sodass die Segmente, die mit diesen Werten übereinstimmen, problemlos ausgelassen werden können.The provided route values match the default values, and the segments corresponding to the default values are safely omitted.

Mit beiden generierten URLs (/Home/Index und /) und dieser Routendefinition wird ein Roundtrip ausgeführt, und es werden dieselben Routenwerte erstellt, die auch zur Generierung der URL verwendet wurden.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.

Hinweis

Eine auf ASP.NET Core MVC basierende App sollte zur Generierung von URLs die Routingfunktion nicht direkt aufrufen, sondern UrlHelper verwenden.An app using ASP.NET Core MVC should use UrlHelper to generate URLs instead of calling into routing directly.

Weitere Informationen zur Generierung von URLs finden Sie im Abschnitt Referenz zur URL-Generierung.For more information on URL generation, see the Url generation reference section.

Verwenden von RoutingmiddlewareUse Routing Middleware

Legen Sie das Microsoft.AspNetCore.App-Metapaket in der Projektdatei der App als Verweis fest.Reference the Microsoft.AspNetCore.App metapackage in the app's project file.

Fügen Sie anschließend dem Dienstcontainer in Startup.ConfigureServices die Routingfunktionalität hinzu:Add routing to the service container in Startup.ConfigureServices:

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

Routen müssen in der Startup.Configure-Methode konfiguriert werden.Routes must be configured in the Startup.Configure method. In der Beispiel-App werden die folgenden APIs verwendet: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);

In der folgenden Tabelle werden die Antworten mit den angegebenen URIs aufgelistet:The following table shows the responses with the given URIs.

URIURI AntwortResponse
/package/create/3 Hallo!Hello! Route values: [operation, create], [id, 3]Route values: [operation, create], [id, 3]
/package/track/-3 Hallo!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/-3/ Hallo!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/ The request falls through, no match. (Die Anforderung ist fehlgeschlagen, keine Übereinstimmung.)The request falls through, no match.
GET /hello/Joe Hi, Joe!Hi, Joe!
POST /hello/Joe The request falls through, matches HTTP GET only (Die Anforderung ist fehlgeschlagen, nur für eine HTTP-GET-Anforderung wird eine Übereinstimmung ermittelt)The request falls through, matches HTTP GET only.
GET /hello/Joe/Smith The request falls through, no match. (Die Anforderung ist fehlgeschlagen, keine Übereinstimmung.)The request falls through, no match.

Das Framework stellt mehrere Erweiterungsmethoden zum Erstellen von Routen zur Verfügung (RequestDelegateRouteBuilderExtensions):The framework provides a set of extension methods for creating routes (RequestDelegateRouteBuilderExtensions):

In den Map[Verb]-Methoden werden Einschränkungen verwendet, um die Route auf das HTTP-Verb im Methodennamen zu beschränken.The Map[Verb] methods use constraints to limit the route to the HTTP Verb in the method name. Beispielsweise unter MapGet und MapVerb.For example, see MapGet and MapVerb.

Referenz für RoutenvorlagenRoute template reference

Token in geschweiften Klammern ({ ... }) definieren Routenparameter, die beim Abgleich der Route gebunden werden.Tokens within curly braces ({ ... }) define route parameters that are bound if the route is matched. Sie können in einem Routensegment mehrere Routenparameter definieren, wenn Sie sie durch einen Literalwert trennen.You can define more than one route parameter in a route segment, but they must be separated by a literal value. {controller=Home}{action=Index} ist z.B. keine gültige Route, da sich zwischen {controller} und {action} kein Literalwert befindet.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Diese Routenparameter müssen einen Namen besitzen und können zusätzliche Attribute aufweisen.These route parameters must have a name and may have additional attributes specified.

Eine Literalzeichenfolge, die nicht den Routenparametern entspricht (z.B. {id}), muss zusammen mit dem Pfadtrennzeichen / mit dem URL-Text übereinstimmen.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. Beim Abgleich von Text wird nicht zwischen Groß-/Kleinbuchstaben unterschieden, und die Übereinstimmung basiert auf der decodierten Repräsentation des URL-Pfads.Text matching is case-insensitive and based on the decoded representation of the URLs path. Damit das Trennzeichen ({ oder }) der Routenparameterliteralzeichenfolge bei einem Abgleich gefunden wird, muss es doppelt vorhanden sein ({{ oder }}), was einem Escapezeichen entspricht.To match a literal route parameter delimiter ({ or }), escape the delimiter by repeating the character ({{ or }}).

Bei einem URL-Muster, durch das ein Dateiname mit einer optionalen Erweiterung erfasst werden soll, sind noch weitere Aspekte zu berücksichtigen.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Dies wird z.B. anhand der Vorlage files/{filename}.{ext?} deutlich.For example, consider the template files/{filename}.{ext?}. Wenn sowohl für filename als auch für ext Werte vorhanden sind, werden beide Werte angegeben.When values for both filename and ext exist, both values are populated. Wenn nur für filename ein Wert in der URL vorhanden ist, wird für die Route eine Zuordnung ermittelt, da der nachstehende Punkt (.) optional ist.If only a value for filename exists in the URL, the route matches because the trailing period (.) is optional. Für die folgenden URLs wird eine Übereinstimmung für die Route ermittelt:The following URLs match this route:

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

Sie können ein (*) oder zwei (**) Sternchen als Präfix für einen Routenparameter verwenden, um eine Bindung zum verbleibenden Teil des URI herzustellen.You can use an asterisk (*) or double asterisk (**) as a prefix to a route parameter to bind to the rest of the URI. Hierbei wird von Catch-All-Parametern gesprochen.These are called a catch-all parameters. Durch blog/{**slug} wird beispielsweise jeder URI ermittelt, der mit /blog beginnt und dahinter einen beliebigen Wert aufweist, der dann dem slug-Routenwert zugeordnet wird.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. Durch Catch-All-Parameter können auch leere Zeichenfolgen gefunden werden.Catch-all parameters can also match the empty string.

Der Catch-All-Parameter schützt die entsprechenden Zeichen (Escaping), wenn die Route verwendet wird, um eine URL, einschließlich Pfadtrennzeichen zu generieren (/).The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. Z.B. generiert die Route foo/{*path} mit den Routenwerten { path = "my/path" }``foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Beachten Sie den umgekehrten Schrägstrich mit Escapezeichen.Note the escaped forward slash. Um Trennzeichen für Roundtrips einsetzen zu können, verwenden Sie das Routenparameterpräfix **.To round-trip path separator characters, use the ** route parameter prefix. Die Route foo/{**path} mit { path = "my/path" } generiert foo/my/path.The route foo/{**path} with { path = "my/path" } generates foo/my/path.

Routenparameter können über mehrere Standardwerte verfügen, die nach dem Parameternamen angegeben werden und durch ein Gleichheitszeichen (=) voneinander getrennt werden.Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Mit {controller=Home} wird beispielsweise Home als Standardwert für controller definiert.For example, {controller=Home} defines Home as the default value for controller. Der Standardwert wird verwendet, wenn kein Wert in der Parameter-URL vorhanden ist.The default value is used if no value is present in the URL for the parameter. Routenparameter sind optional, wenn am Ende des Parameternamens ein Fragezeichen (?) angefügt wird, z. B. id?.Route parameters are made optional by appending a question mark (?) to the end of the parameter name, as in id?. Der Unterschied zwischen optionalen Parametern und Routenparametern mit einem Standardwert besteht darin, dass mithilfe der letzteren immer ein Wert erzeugt wird. Ein optionaler Parameter verfügt demgegenüber nur dann über einen Wert, wenn ein solcher von der Anforderungs-URL bereitgestellt wird.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.

Routenparameter können Einschränkungen aufweisen, die mit dem gebundenen Routenwert der URL übereinstimmen müssen.Route parameters may have constraints that must match the route value bound from the URL. Eine Inline-Einschränkung für einen Routenparameter geben Sie an, indem Sie hinter dem Namen des Routenparameters einen Doppelpunkt (:) und einen Einschränkungsnamen hinzufügen.Adding a colon (:) and constraint name after the route parameter name specifies an inline constraint on a route parameter. Wenn für die Einschränkung Argumente erforderlich sind, werden diese nach dem Einschränkungsnamen in Klammern ((...)) eingeschlossen.If the constraint requires arguments, they're enclosed in parentheses ((...)) after the constraint name. Mehrere Inline-Einschränkungen können festgelegt werden, indem ein weiterer Doppelpunkt (:) und Einschränkungsname hinzugefügt werden.Multiple inline constraints can be specified by appending another colon (:) and constraint name.

Der Einschränkungsname und die Argumente werden dem IInlineConstraintResolver-Dienst übergeben, wodurch eine Instanz von IRouteConstraint für die URL-Verarbeitung erstellt werden kann.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. In der Routenvorlage blog/{article:minlength(10)} wird beispielsweise die Einschränkung minlength mit dem Argument 10 festgelegt.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Weitere Informationen zu Routeneinschränkungen und eine Liste der vom Framework bereitgestellten Einschränkungen finden Sie im Abschnitt Referenz zu Routeneinschränkungen.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Routenparameter können darüber hinaus über Parametertransformatoren verfügen, die den Wert eines Parameters beim Generieren von Links umwandeln und Aktionen und Seiten an URLs anpassen.Route parameters may also have parameter transformers, which transform a parameter's value when generating links and matching actions and pages to URLs. Wie Einschränkungen können auch Parametertransformatoren einem Routenparameter inline hinzugefügt werden, indem ein Doppelpunkt (:) und der Name des Transformators hinter dem Namen des Routenparameters hinzugefügt werden.Like constraints, parameter transformers can be added inline to a route parameter by adding a colon (:) and transformer name after the route parameter name. In der Routenvorlage blog/{article:slugify} wird beispielsweise der Transformator slugify festgelegt.For example, the route template blog/{article:slugify} specifies a slugify transformer. Weitere Informationen zu Parametertransformatoren finden Sie im Abschnitt Parametertransformatorreferenz.For more information on parameter transformers, see the Parameter transformer reference section.

Die folgende Tabelle enthält Beispielvorlagen für Routen und deren Verhalten.The following table demonstrates example route templates and their behavior.

RoutenvorlageRoute Template Beispiel-URI für ÜbereinstimmungExample Matching URI Der Anforderungs-URI…The request URI…
hello /hello Nur für den Pfad /hello wird eine Übereinstimmung ermittelt.Only matches the single path /hello.
{Page=Home} / Eine Übereinstimmung wird ermittelt, und Page wird auf Home festgelegt.Matches and sets Page to Home.
{Page=Home} /Contact Eine Übereinstimmung wird ermittelt, und Page wird auf Contact festgelegt.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Stimmt mit dem Products-Controller und der List-Aktion überein.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Stimmt mit dem Products-Controller und der Details-Aktion (id auf 123 festgelegt) überein.Maps to the Products controller and Details action (id set to 123).
{controller=Home}/{action=Index}/{id?} / Stimmt mit dem Home-Controller und der Index-Aktion überein (id wird ignoriert).Maps to the Home controller and Index method (id is ignored).

Mit Vorlagen lässt sich Routing besonders leicht durchführen.Using a template is generally the simplest approach to routing. Einschränkungen und Standardwerte können auch außerhalb der Routenvorlage angegeben werden.Constraints and defaults can also be specified outside the route template.

Tipp

Wenn Sie die Protokollierung aktivieren, erfahren Sie, wie die integrierten Routingimplementierungen (z.B. Route) Zuordnungen für Anforderungen ermitteln.Enable Logging to see how the built-in routing implementations, such as Route, match requests.

Reservierte RoutingnamenReserved routing names

Die folgenden Schlüsselwörter sind reservierte Namen und können nicht als Routennamen oder Parameter verwendet werden:The following keywords are reserved names and can't be used as route names or parameters:

  • action
  • area
  • controller
  • handler
  • page

Referenz für RouteneinschränkungenRoute constraint reference

Routeneinschränkungen werden angewendet, wenn eine Übereinstimmung mit der eingehenden URL gefunden wurde und der URL-Pfad in Routenwerten mit Token versehen wird.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. In der Regel wird mit Routeneinschränkungen der Routenwert der zugehörigen Vorlage geprüft. Dabei wird bestimmt, ob der Wert gültig ist.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. Für einige Routeneinschränkungen werden anstelle des Routenwerts andere Daten verwendet, um zu ermitteln, ob das Routing einer Anforderung möglich ist.Some route constraints use data outside the route value to consider whether the request can be routed. HttpMethodRouteConstraint kann beispielsweise auf der Grundlage des HTTP-Verbs eine Anforderung entweder annehmen oder ablehnen.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Einschränkungen werden in Routinganforderungen und bei der Linkgenerierung verwendet.Constraints are used in routing requests and link generation.

Warnung

Verwenden Sie keine Einschränkungen für die Eingabeüberprüfung.Don't use constraints for input validation. Wenn bei der Eingabevalidierung Einschränkungen verwendet werden, lösen ungültige Eingaben den Fehler 404 - Not Found (404 – Nicht gefunden) aus. Stattdessen sollte jedoch der Fehler 400 - Bad Request (400 – Fehlerhafte Anforderung) ausgelöst und mit einer entsprechenden Fehlermeldung angezeigt werden.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. Verwenden Sie Routeneinschränkungen nicht, um Eingaben für eine bestimmte Route zu überprüfen, sondern um ähnlichen Routen zu unterscheiden.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

In der folgenden Tabelle werden Beispiele für Routeneinschränkungen und deren zu erwartendes Verhalten beschriebe.The following table demonstrates example route constraints and their expected behavior.

ConstraintConstraint BeispielExample Beispiele für ÜbereinstimmungenExample matches HinweiseNotes
int {id:int} 123456789, -123456789123456789, -123456789 Für jeden Integer wird eine Übereinstimmung ermittelt.Matches any integer.
bool {active:bool} true, FALSEtrue, FALSE Entspricht true oder false.Matches true or false. Groß-/Kleinschreibung wird nicht beachtet.Case-insensitive.
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Entspricht einem gültigen DateTime-Wert in der invarianten Kultur.Matches a valid DateTime value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Entspricht einem gültigen decimal-Wert in der invarianten Kultur.Matches a valid decimal value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen double-Wert in der invarianten Kultur.Matches a valid double value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen float-Wert in der invarianten Kultur.Matches a valid float value in the invariant culture. Siehe vorherige Warnung.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} Für einen gültigen Guid-Wert wird eine Übereinstimmung ermittelt.Matches a valid Guid value.
long {ticks:long} 123456789, -123456789123456789, -123456789 Für einen gültigen long-Wert wird eine Übereinstimmung ermittelt.Matches a valid long value.
minlength(value) {username:minlength(4)} Rick Die Zeichenfolge muss mindestens eine Länge von 4 Zeichen aufweisen.String must be at least 4 characters.
maxlength(value) {filename:maxlength(8)} MyFile Die Zeichenfolge hat maximal 8 Zeichen.String has maximum of 8 characters.
length(length) {filename:length(12)} somefile.txt Die Zeichenfolge muss genau 12 Zeichen aufweisen.String must be exactly 12 characters long.
length(min,max) {filename:length(8,16)} somefile.txt Die Zeichenfolge muss mindestens 8 und darf maximal 16 Zeichen lang sein.String must be at least 8 and has maximum of 16 characters.
min(value) {age:min(18)} 19 Der ganzzahlige Wert muss mindestens 18 sein.Integer value must be at least 18.
max(value) {age:max(120)} 91 Der ganzzahlige Wert darf höchstens 120 sein.Integer value maximum of 120.
range(min,max) {age:range(18,120)} 91 Der ganzzahlige Wert muss mindestens 18 und darf höchstens 120 sein.Integer value must be at least 18 and maximum of 120.
alpha {name:alpha} Rick Die Zeichenfolge muss aus mindestens einem alphabetische Zeichen bestehen, a-z.String must consist of one or more alphabetical characters a-z. Groß-/Kleinschreibung wird nicht beachtet.Case-insensitive.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 Die Zeichenfolge muss mit dem regulären Ausdruck übereinstimmen.String must match the regular expression. Weitere Informationen finden Sie unter Tipps zum Definieren eines regulären Ausdrucks.See tips about defining a regular expression.
required {name:required} Rick Hierdurch wird erzwungen, dass ein Wert, der kein Parameter ist, für die URL-Generierung vorhanden sein muss.Used to enforce that a non-parameter value is present during URL generation.

Auf einen einzelnen Parameter können mehrere durch Doppelpunkte getrennte Einschränkungen angewendet werden.Multiple, colon-delimited constraints can be applied to a single parameter. Durch die folgende Einschränkung wird ein Parameter beispielsweise auf einen Integerwert größer oder gleich 1 beschränkt: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) { }

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet.Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.These constraints assume that the URL is non-localizable. Die vom Framework bereitgestellten Routeneinschränkungen ändern nicht die Werte, die in Routenwerten gespeichert sind.The framework-provided route constraints don't modify the values stored in route values. Alle Routenwerte, die aus der URL analysiert werden, werden als Zeichenfolgen gespeichert.All route values parsed from the URL are stored as strings. Durch die float-Einschränkung wird beispielsweise versucht, den Routenwert in einen Gleitkommawert zu konvertieren. Mit dem konvertierten Wert wird allerdings nur überprüft, ob eine Umwandlung überhaupt möglich ist.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.

Reguläre AusdrückeRegular expressions

Im ASP.NET Core-Framework wird dem Konstruktor für reguläre Ausdrücke RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant hinzugefügt.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Eine Beschreibung dieser Member finden Sie unter RegexOptions.See RegexOptions for a description of these members.

In regulären Ausdrücken werden Trennzeichen und Token verwendet, die auch beim Routing und in der Programmiersprache C# in ähnlicher Weise verwendet werden.Regular expressions use delimiters and tokens similar to those used by routing and the C# language. Token, die reguläre Ausdrücke enthalten, müssen mit einem Escapezeichen versehen werden.Regular expression tokens must be escaped. Der zu verwendende reguläre Ausdruck ^\d{3}-\d{2}-\d{4}$ für das Routing:To use the regular expression ^\d{3}-\d{2}-\d{4}$ in routing:

  • Der Ausdruck muss den einfachen umgekehrten Schrägstrich \ enthalten, der im Quellcode in der Zeichenfolge als doppelter umgekehrter Schrägstrich \\ vorhanden ist.The expression must have the single backslash \ characters provided in the string as double backslash \\ characters in the source code.
  • Der reguläre Ausdruck muss \\ verwenden, um die Zeichenfolge \ mit Escapezeichen zu versehen.The regular expression must us \\ in order to escape the \ string escape character.
  • Für den regulären Ausdruck ist \\ nicht erforderlich, wenn ausführliche Zeichenfolgenliterale verwendet werden.The regular expression doesn't require \\ when using verbatim string literals.

Wenn Sie Trennzeichen für Routenparameter mit Escapezeichen versehen möchten ({, }, [, ]), geben Sie jedes Zeichen im Ausdruck doppelt ein ({{, }, [[, ]]).To escape routing parameter delimiter characters {, }, [, ], double the characters in the expression {{, }, [[, ]]. In der folgenden Tabelle werden reguläre Ausdrücke und Ausdrücke aufgeführt, die mit Escapezeichen versehen sind:The following table shows a regular expression and the escaped version:

Regulärer AusdruckRegular Expression Mit Escapezeichen versehener regulärer AusdruckEscaped Regular Expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Beim Routing verwendete reguläre Ausdrücke beginnen oft mit einem Caretzeichen (^) und stellen die Startposition der Zeichenfolge dar.Regular expressions used in routing often start with the caret ^ character and match starting position of the string. Die Ausdrücke enden häufig mit einem Dollarzeichen ($) und stellen das Ende der Zeichenfolge dar.The expressions often end with the dollar sign $ character and match end of the string. Mit den Zeichen ^ und $ wird sichergestellt, dass der reguläre Ausdruck mit dem vollständigen Routenparameterwert übereinstimmt.The ^ and $ characters ensure that the regular expression match the entire route parameter value. Ohne die Zeichen ^ und $ werden mit dem regulären Ausdruck alle Teilzeichenfolgen ermittelt, was häufig nicht gewünscht ist.Without the ^ and $ characters, the regular expression match any substring within the string, which is often undesirable. In der folgenden Tabelle finden Sie Beispiele für reguläre Ausdrücke. Außerdem wird erklärt, warum ein Abgleich erfolgreich ist oder fehlschlägt.The following table provides examples and explains why they match or fail to match.

expressionExpression ZeichenfolgeString MatchMatch KommentarComment
[a-z]{2} hellohello JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} 123abc456123abc456 JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} mzmz JaYes Ausdruck stimmt übereinMatches expression
[a-z]{2} MZMZ JaYes keine Unterscheidung zwischen Groß-/KleinbuchstabenNot case sensitive
^[a-z]{2}$ hellohello NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above

Weitere Informationen zur Syntax von regulären Ausdrücken finden Sie unter Sprachelemente für reguläre Ausdrücke – Kurzübersicht.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Einen regulären Ausdruck können Sie verwenden, um einen Parameter auf zulässige Werte einzuschränken.To constrain a parameter to a known set of possible values, use a regular expression. Mit {action:regex(^(list|get|create)$)} werden beispielsweise für den action-Routenwert nur die Werte list, get oder create abgeglichen.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Wenn die Zeichenfolge ^(list|get|create)$ dem Einschränkungswörterbuch übergeben wird, führt dies zum gleichen Ergebnis.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Auch Einschränkungen, die dem zugehörigen Wörterbuch hinzugefügt werden und mit keiner vorgegebenen Einschränkung übereinstimmen , werden als reguläre Ausdrücke behandelt. Dies gilt allerdings nicht für Inline-Einschränkungen in einer Vorlage.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.

Benutzerdefinierte RouteneinschränkungenCustom route constraints

Zusätzlich zu den integrierten Routeneinschränkungen können benutzerdefinierte Routeneinschränkungen durch Implementierung der IRouteConstraint-Schnittstelle erstellt werden.In addition to the built-in route constraints, custom route constraints can be created by implementing the IRouteConstraint interface. Die IRouteConstraint-Schnittstelle enthält eine einzelne Methode, Match, die true zurückgibt, wenn die Einschränkung erfüllt wird, und andernfalls false.The IRouteConstraint interface contains a single method, Match, which returns true if the constraint is satisfied and false otherwise.

Zum Verwenden einer benutzerdefinierten IRouteConstraint muss der Routeneinschränkungstyp bei der ConstraintMap der App im Dienstcontainer der App registriert werden.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the app's service container. Eine ConstraintMap ist ein Wörterbuch, das Routeneinschränkungsschlüssel IRouteConstraint-Implementierungen zuordnet, die diese Einschränkungen überprüfen.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Die ConstraintMap einer App kann in Startup.ConfigureServices entweder als Teil eines services.AddRouting-Aufrufs oder durch direktes Konfigurieren von RouteOptions mit services.Configure<RouteOptions> aktualisiert werden.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>. Zum Beispiel:For example:

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

Die Einschränkung kann dann auf die übliche Weise mit dem bei der Registrierung des Einschränkungstyps angegebenen Namen auf Routen angewendet werden.The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. Zum Beispiel:For example:

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

ParametertransformatorreferenzParameter transformer reference

Parametertransformatoren:Parameter transformers:

  • Werden beim Generieren eines Links für eine Route ausgeführt.Execute when generating a link for a Route.
  • Implementieren Sie Microsoft.AspNetCore.Routing.IOutboundParameterTransformer.Implement Microsoft.AspNetCore.Routing.IOutboundParameterTransformer.
  • Werden mithilfe von ConstraintMap konfiguriert.Are configured using ConstraintMap.
  • Nehmen den Routenwert des Parameters an und transformieren ihn in einen neuen Zeichenfolgenwert.Take the parameter's route value and transform it to a new string value.
  • Haben die Verwendung des transformierten Wert in einem generierten Link zur Folge.Result in using the transformed value in the generated link.

Beispielsweise generiert ein benutzerdefinierter Parametertransformator slugify im Routenmuster blog\{article:slugify} mit Url.Action(new { article = "MyTestArticle" })``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.

Um einen Parametertransformator in einem Routenmuster zu verwenden, konfigurieren Sie ihn zuerst mit ConstraintMap in 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);
});

Parametertransformatoren werden auch von Frameworks verwendet, um den URI zu transformieren, zu dem ein Endpunkt aufgelöst wird.Parameter transformers are used by the framework to transform the URI where an endpoint resolves. Beispielsweise verwendet ASP.NET Core MVC Parametertransformatoren zum Transformieren des Routenwerts, der zum Zuordnen einer area, eines controller, einer action und einer page verwendet wird.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?}");

Mit der vorstehenden Route wird die Aktion SubscriptionManagementController.GetAll dem URI /subscription-management/get-all zugeordnet.With the preceding route, the action SubscriptionManagementController.GetAll is matched with the URI /subscription-management/get-all. Ein Parametertransformator ändert nicht die zum Generieren eines Links verwendeten Routenwerte.A parameter transformer doesn't change the route values used to generate a link. Beispielsweise gibt Url.Action("GetAll", "SubscriptionManagement")``/subscription-management/get-all aus.For example, Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core bietet API-Konventionen für die Verwendung von Parametertransformatoren mit generierten Routen:ASP.NET Core provides API conventions for using a parameter transformers with generated routes:

  • ASP.NET Core MVC verwendet die Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention-API-Konvention.ASP.NET Core MVC has the Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention API convention. Diese Konvention wendet einen angegebenen Parametertransformator auf alle Attributrouten in der App an.This convention applies a specified parameter transformer to all attribute routes in the app. Der Parametertransformator transformiert Attributroutentoken, wenn diese ersetzt werden.The parameter transformer transforms attribute route tokens as they are replaced. Weitere Informationen finden Sie unter Verwenden eines Parametertransformators zum Anpassen der Tokenersetzung.For more information, see Use a parameter transformer to customize token replacement.
  • Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention Pages verwendet die Razor-API-Konvention.Razor Pages has the Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention API convention. Diese Konvention wendet einen angegebenen Parametertransformator auf alle automatisch erkannten Razor Pages-Seiten an.This convention applies a specified parameter transformer to all automatically discovered Razor Pages. Der Parametertransformator transformiert die Ordner- und Dateinamensegmente von Razor Pages-Routen.The parameter transformer transforms the folder and file name segments of Razor Pages routes. Weitere Informationen finden Sie unter Verwenden eines Parametertransformators zum Anpassen von Seitenrouten.For more information, see Use a parameter transformer to customize page routes.

Referenz für URL-GenerierungURL generation reference

Im folgenden Beispiel wird gezeigt, wie Sie einen Link zu einer Route unter Berücksichtigung eines vorhandenen Wörterbuchs mit Routenwerten und einer RouteCollection erstellen.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/>");
});

Die VirtualPath-Eigenschaft, die am Ende des obigen Beispiels erstellt wird, hat den Wert /package/create/123.The VirtualPath generated at the end of the preceding sample is /package/create/123. Das Wörterbuch stellt die Routenwerte von operation und id aus der Vorlage „Track Package Route“ (package/{operation}/{id}) bereit.The dictionary supplies the operation and id route values of the "Track Package Route" template, package/{operation}/{id}. Weitere Informationen finden Sie im Beispielcode im Abschnitt Verwenden von Routingmiddleware oder in der Beispiel-App.For details, see the sample code in the Use Routing Middleware section or the sample app.

Der zweite Parameter für den VirtualPathContext-Konstruktor ist eine Auflistung von Umgebungswerten.The second parameter to the VirtualPathContext constructor is a collection of ambient values. Mit diesen lässt sich leicht die Anzahl der Werte einschränken, die ein Entwickler innerhalb eines Anforderungskontexts angeben muss.Ambient values are convenient to use because they limit the number of values a developer must specify within a request context. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt.The current route values of the current request are considered ambient values for link generation. In einer ASP.NET Core-MVC-App müssen Sie innerhalb der About-Aktion von HomeController nicht den Controllerroutenwert angeben, um eine Verknüpfung mit der Index-Aktion herzustellen, da der Umgebungswert von Home verwendet wird.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.

Umgebungswerte, die mit keinem Parameter übereinstimmen, werden ignoriert.Ambient values that don't match a parameter are ignored. Außerdem werden Umgebungswerte ignoriert, wenn ein explizit angegebener Wert den betreffenden Umgebungswert außer Kraft setzt.Ambient values are also ignored when an explicitly provided value overrides the ambient value. Der Abgleich in der URL wird von links nach rechts ausgeführt.Matching occurs from left to right in the URL.

Explizit bereitgestellte Werte, für die keine Übereinstimmungen mit einem Routensegment ermittelt werden, werden der Abfragezeichenfolge hinzugefügt.Values explicitly provided but that don't match a segment of the route are added to the query string. In der folgenden Tabelle werden die Ergebnisse dargestellt, die aus der Verwendung der Routenvorlage {controller}/{action}/{id?} hervorgehen:The following table shows the result when using the route template {controller}/{action}/{id?}.

UmgebungswerteAmbient Values Explizite WerteExplicit Values ErgebnisResult
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

Wenn eine Route über einen Standardwert verfügt, der keinem Parameter entspricht, und dieser Wert explizit bereitgestellt wird, muss er dem Standardwert entsprechen: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" });

Für diese Route wird nur dann ein Link generiert, wenn die übereinstimmenden Werte für controller und action bereitgestellt werden.Link generation only generates a link for this route when the matching values for controller and action are provided.

Komplexe SegmenteComplex segments

Komplexe Segmente (z.B. [Route("/x{token}y")]) werden von rechts nach links auf eine nicht gierige Weise durch entsprechende Literale verarbeitet.Complex segments (for example [Route("/x{token}y")]) are processed by matching up literals from right to left in a non-greedy way. Unter diesem Code finden Sie eine ausführliche Erklärung für das Abgleichen komplexer Segmente.See this code for a detailed explanation of how complex segments are matched. Das Codebeispiel wird von ASP.NET Core nicht verwendet, aber es bietet eine gute Erklärung komplexer Segmente.The code sample is not used by ASP.NET Core, but it provides a good explanation of complex segments.

Beim Routing werden Anforderungs-URIs Routenhandlern zugeordnet und Anforderungen weitergeleitet.Routing is responsible for mapping request URIs to route handlers and dispatching an incoming requests. Routen werden in der App definiert und beim Start der App konfiguriert.Routes are defined in the app and configured when the app starts. Eine Route kann optional Werte aus der URL extrahieren, die in der Anforderung enthalten ist. Diese Werte können anschließend für die Verarbeitung der Anforderung verwendet werden.A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. Unter Verwendung von konfigurierten Routen aus der App können durch das Routing URLs erstellt werden, die Routenhandlern zugeordnet werden.Using configured routes from the app, routing is able to generate URLs that map to route handlers.

Wenn Sie die aktuellsten Routingszenarios in ASP.NET Core 2.1 verwenden möchten, geben Sie die Kompatibilitätsversion zur Registrierung der MVC-Dienste in Startup.ConfigureServices an: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);

Wichtig

In diesem Artikel wird das Low-Level-Routing in ASP.NET Core beschrieben.This document covers low-level ASP.NET Core routing. Weitere Informationen zum Routing mit ASP.NET Core MVC finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.For information on ASP.NET Core MVC routing, see Routing zu Controlleraktionen in ASP.NET Core. Weitere Informationen zu Routingkonventionen in Razor Pages finden Sie unter Razor Pages: Routen- und App-Konventionen in ASP.NET Core.For information on routing conventions in Razor Pages, see Razor Pages: Routen- und App-Konventionen in ASP.NET Core.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

RoutinggrundlagenRouting basics

Für die meisten Apps sollte eine grundlegendes und beschreibendes Routingschema ausgewählt werden, um lesbare und aussagekräftige URLs zu erhalten.Most apps should choose a basic and descriptive routing scheme so that URLs are readable and meaningful. Für die konventionelle Standardroute {controller=Home}/{action=Index}/{id?} gilt:The default conventional route {controller=Home}/{action=Index}/{id?}:

  • Sie unterstützt ein grundlegendes und beschreibendes Routingschema.Supports a basic and descriptive routing scheme.
  • Sie stellt einen nützlichen Startpunkt für benutzeroberflächenbasierte Apps dar.Is a useful starting point for UI-based apps.

Entwickler fügen in der Regel in speziellen Situationen (z. B. bei Blog- und E-Commerce-Endpunkten) durch Attributrouting oder dedizierte konventionelle Routen zusätzliche kurze Routen zu stark frequentierten Bereichen der App hinzu.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.

Web-APIs sollten das Attributrouting verwenden, um die Funktionalität der App als einen Satz von Ressourcen zu modellieren, bei denen Vorgänge durch HTTP-Verben dargestellt werden.Web APIs should use attribute routing to model the app's functionality as a set of resources where operations are represented by HTTP verbs. Dies bedeutet, dass viele Vorgänge (z.B. GET, POST) für dieselbe logische Ressource dieselbe URL verwenden.This means that many operations (for example, GET, POST) on the same logical resource will use the same URL. Das Attributrouting bietet eine Ebene der Steuerung, die für einen sorgfältigen Entwurf des öffentlichen Endpunktlayouts einer API erforderlich ist.Attribute routing provides a level of control that's needed to carefully design an API's public endpoint layout.

Razor Pages-Apps verwenden konventionelles Standardrouting, um benannte Ressourcen im Pages-Ordner einer App bereitzustellen.Razor Pages apps use default conventional routing to serve named resources in the Pages folder of an app. Außerdem gibt es weitere Konventionen zum Anpassen des Routingverhaltens für Razor Pages.Additional conventions are available that allow you to customize Razor Pages routing behavior. Weitere Informationen finden Sie unter Einführung in Razor Pages in ASP.NET Core und Razor Pages: Routen- und App-Konventionen in ASP.NET Core.For more information, see Einführung in Razor Pages in ASP.NET Core and Razor Pages: Routen- und App-Konventionen in ASP.NET Core.

Die Unterstützung zum Generieren von URLs ermöglicht es, die App ohne Hartcodierung der URLs zum Verlinken der App zu entwickeln.URL generation support allows the app to be developed without hard-coding URLs to link the app together. Auf diese Weise kann mit einer grundlegenden Routingkonfiguration begonnen werden, und die Routen können geändert werden, wenn das Ressourcenlayout der App festgelegt wurde.This support allows for starting with a basic routing configuration and modifying the routes after the app's resource layout is determined.

Beim Routing werden Routenimplementierungen von IRouter für Folgendes verwendet:Routing uses routes implementations of IRouter to:

  • Zuordnen von eingehenden Anforderungen zu RoutenhandlernMap incoming requests to route handlers.
  • Generieren von URLs für AntwortenGenerate the URLs used in responses.

Eine App verfügt standardmäßig über genau eine Routensammlung.By default, an app has a single collection of routes. Wenn eine Anforderung eingeht, werden die Routen in der Sammlung in der Reihenfolge verarbeitet, in der sie in der Sammlung aufgelistet werden.When a request arrives, the routes in the collection are processed in the order that they exist in the collection. Dann versucht das Framework, eine eingehende Anforderungs-URL einer Route in der Sammlung zuzuordnen, indem es die RouteAsync-Methode für jede Route in der Sammlung aufruft.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. Bei einer Antwort kann Routing verwendet werden, um URLs zu generieren (z.B. für Umleitungen oder Links), die auf Routeninformationen basieren. Dadurch wird die Erstellung von hartcodierten URLs verhindert, was wiederrum die Wartbarkeit verbessert.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.

Das Routingsystem weist die folgenden Eigenschaften auf:The routing system has the following characteristics:

  • Die Syntax der Routenvorlage wird zum Definieren von Routen mit Routenparametern verwendet, die mit Token versehen sind.Route template syntax is used to define routes with tokenized route parameters.
  • Sowohl die konventionelle Endpunktkonfiguration als auch die Endpunktkonfiguration mit Attributen ist zulässig.Conventional-style and attribute-style endpoint configuration is permitted.
  • IRouteConstraint wird verwendet, um zu bestimmen, ob ein URL-Parameter einen gültigen Wert für eine bestimmte Endpunkteinschränkung enthält.IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.
  • App-Modelle wie MVC bzw Razor Pages registrieren sämtliche Routen, für die die Implementierung von Routingszenarios vorhersagbar ist.App models, such as MVC/Razor Pages, register all of their routes, which have a predictable implementation of routing scenarios.
  • Bei einer Antwort kann Routing verwendet werden, um URLs zu generieren (z.B. für Umleitungen oder Links), die auf Routeninformationen basieren. Dadurch wird die Erstellung von hartcodierten URLs verhindert, was wiederrum die Wartbarkeit verbessert.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.
  • Die URL-Generierung basiert auf Routen, die beliebige Erweiterbarkeit unterstützen.URL generation is based on routes, which support arbitrary extensibility. IUrlHelper bietet Methoden zum Erstellen von URLs.IUrlHelper offers methods to build URLs.

Die Routingfunktionalität wird über die Klasse RouterMiddleware mit der Middlewarepipeline verbunden.Routing is connected to the middleware pipeline by the RouterMiddleware class. ASP.NET Core-MVC fügt im Rahmen der Konfiguration die Routingfunktionalität der Middlewarepipeline hinzu und verarbeitet das Routing in MVC- und Razor Pages-Apps.ASP.NET Core MVC adds routing to the middleware pipeline as part of its configuration and handles routing in MVC and Razor Pages apps. Informationen darüber, wie Sie Routing als eigenständige Komponente verwenden, finden Sie im Abschnitt Verwenden von Routingmiddleware.To learn how to use routing as a standalone component, see the Use Routing Middleware section.

URL-ZuordnungURL matching

Bei einer URL-Zuordnung werden eingehende Anforderungen durch Routing an einen Handler gesendet.URL matching is the process by which routing dispatches an incoming request to a handler. Für diesen Prozess werden die Daten des URL-Pfads verwendet. Es können jedoch auch alle Daten der Anforderung genutzt werden.This process is based on data in the URL path but can be extended to consider any data in the request. Für die Skalierung der Größe und Komplexität einer App ist das Versenden von Anforderungen an unterschiedliche Handler entscheidend.The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

Eingehende Anforderungen werden vom RouterMiddleware-Objekt bearbeitet, das die Methode RouteAsync für alle Routen nacheinander aufruft.Incoming requests enter the RouterMiddleware, which calls the RouteAsync method on each route in sequence. In der IRouter-Instanz wird entschieden, ob die Anforderung verarbeitet wird, indem für den RouteContext.Handler ein RequestDelegate-Delegat festgelegt wird, der nicht NULL ist.The IRouter instance chooses whether to handle the request by setting the RouteContext.Handler to a non-null RequestDelegate. Wenn von einer Route ein Handler für die Anforderung festgelegt wird, endet die Routenverarbeitung, und der Handler wird zur Verarbeitung der Anforderung aufgerufen.If a route sets a handler for the request, route processing stops, and the handler is invoked to process the request. Wenn kein Routenhandler gefunden wird, um die Anforderung zu verarbeiten, leitet die Middleware die Anforderung an die nächste Middleware in der Anforderungspipeline weiter.If no route handler is found to process the request, the middleware hands the request off to the next middleware in the request pipeline.

Die Haupteingabe für RouteAsync ist der RouteContext.HttpContext, der der aktuellen Anforderung zugeordnet ist.The primary input to RouteAsync is the RouteContext.HttpContext associated with the current request. RouteContext.Handler und RouteContext.RouteData sind Ausgaben, die festgelegt werden, nachdem eine Route zugeordnet wurde.The RouteContext.Handler and RouteContext.RouteData are outputs set after a route is matched.

Eine Zuordnung, die RouteAsync aufruft, legt außerdem die Eigenschaften von RouteContext.RouteData auf Grundlage der bisher verarbeiteten Anforderungen auf entsprechende Werte fest.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 ist ein Wörterbuch mit Routenwerten, das aus der Route erstellt wird.RouteData.Values is a dictionary of route values produced from the route. Die Werte werden in der Regel durch die Tokenisierung der URL ermittelt und können so verwendet werden, dass Benutzereingaben akzeptiert oder weitere Entscheidungen in der App zum Versenden von Anforderungen getroffen werden.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 ist eine Eigenschaftensammlung mit zusätzlichen Daten zur zugeordneten Route.RouteData.DataTokens is a property bag of additional data related to the matched route. DataTokens werden bereitgestellt, damit sich jeder Route Zustandsdaten zuordnen lassen, sodass in der App später Entscheidungen auf Grundlage der zugeordneten Route getroffen werden können.DataTokens are provided to support associating state data with each route so that the app can make decisions based on which route matched. Diese Werte werden vom Entwickler vorgegeben und beeinflussen das Routingverhalten in keiner Weise.These values are developer-defined and do not affect the behavior of routing in any way. Außerdem können im Gegensatz zu RouteData.Values, die sich in bzw. aus Zeichenfolgen konvertieren lassen müssen, Werte in RouteData.DataTokens einem beliebigen Typ entsprechen.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 ist eine Liste der Routen, die an der Zuordnung der Anforderung beteiligt waren.RouteData.Routers is a list of the routes that took part in successfully matching the request. Routen können in anderen Routen geschachtelt werden.Routes can be nested inside of one another. Die Routers-Eigenschaft stellt den Pfad mithilfe der logischen Routenstruktur dar, die zu der Zuordnung geführt hat.The Routers property reflects the path through the logical tree of routes that resulted in a match. Üblicherweise ist das erste Element in Routers die Routensammlung. Dieses sollte zur URL-Generierung verwendet werden.Generally, the first item in Routers is the route collection and should be used for URL generation. Das letzte Element in Routers ist der Routenhandler, für den eine Zuordnung vorgenommen wurde.The last item in Routers is the route handler that matched.

URL-GenerierungURL generation

Bei der URL-Generierung wird durch Routing ein URL-Pfad basierend auf mehreren Routenwerten erstellt.URL generation is the process by which routing can create a URL path based on a set of route values. Dies ermöglicht eine logische Trennung zwischen den Routenhandlern und den URLs, die auf diese zugreifen.This allows for a logical separation between route handlers and the URLs that access them.

Auch für die URL-Generierung wird ein iterativer Prozess verwendet, bei dem allerdings zuerst vom Benutzer- oder Frameworkcode die GetVirtualPath-Methode der Routensammlung aufgerufen wird.URL generation follows a similar iterative process, but it starts with user or framework code calling into the GetVirtualPath method of the route collection. Nacheinander wird für jede Route die zugehörige GetVirtualPath-Methode aufgerufen, bis ein VirtualPathData-Objekt zurückgegeben wird, dessen Wert nicht NULL ist.Each route has its GetVirtualPath method called in sequence until a non-null VirtualPathData is returned.

Die primären Eingaben für GetVirtualPath sind:The primary inputs to GetVirtualPath are:

Für Routen werden überwiegend die Routenwerte verwendet, die von Values und AmbientValues bereitgestellt werden. Dadurch wird ermittelt, ob eine URL generiert werden kann und welche Werte diese enthalten soll.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. AmbientValues sind Routenwerte, die durch die Zuordnung zur aktuellen Anforderung erstellt wurden.The AmbientValues are the set of route values that were produced from matching the current request. Im Gegensatz dazu sind Values die Routenwerte, die angeben, wie die gewünschte URL für den aktuellen Vorgang generiert werden soll.In contrast, Values are the route values that specify how to generate the desired URL for the current operation. HttpContext wird bereitgestellt, falls für eine Route Dienste oder zusätzliche Daten, die mit dem aktuellen Kontext verknüpft sind, abgerufen werden müssen.The HttpContext is provided in case a route should obtain services or additional data associated with the current context.

Tipp

VirtualPathContext.Values kann als Menge von überschriebenen Eigenschaften für VirtualPathContext.AmbientValues betrachtet werden.Think of VirtualPathContext.Values as a set of overrides for the VirtualPathContext.AmbientValues. Bei der URL-Generierung wird versucht, Routenwerte der aktuellen Anforderung wiederzuverwenden, um so URLs für Links generieren zu können, die dieselbe Route oder dieselben Routenwerte verwenden.URL generation attempts to reuse route values from the current request to generate URLs for links using the same route or route values.

Die Ausgabe von GetVirtualPath ist ein VirtualPathData-Objekt.The output of GetVirtualPath is a VirtualPathData. VirtualPathData verhält sich analog zu RouteData.VirtualPathData is a parallel of RouteData. VirtualPathData enthält das VirtualPath-Objekt für die Ausgabe-URL und einige zusätzlichen Eigenschaften, die von der Route festgelegt werden sollten.VirtualPathData contains the VirtualPath for the output URL and some additional properties that should be set by the route.

Die VirtualPathData.VirtualPath-Eigenschaft enthält den virtuellen Pfad, der von der Route erstellt wird.The VirtualPathData.VirtualPath property contains the virtual path produced by the route. Je nach Anforderungen muss der Pfad eventuell noch weiter verarbeitet werden.Depending on your needs, you may need to process the path further. Wenn die generierte URL in HTML gerendert werden soll, müssen Sie den App-Basispfad voranstellen.If you want to render the generated URL in HTML, prepend the base path of the app.

VirtualPathData.Router ist ein Verweis auf die Route, mit der die URL generiert wurde.The VirtualPathData.Router is a reference to the route that successfully generated the URL.

Die VirtualPathData.DataTokens-Eigenschaften stellen ein Wörterbuch mit zusätzlichen Daten zur Route dar, mit der die URL generiert wurde.The VirtualPathData.DataTokens properties is a dictionary of additional data related to the route that generated the URL. Diese Eigenschaften verhalten sich analog zu RouteData.DataTokens.This is the parallel of RouteData.DataTokens.

Erstellen von RoutenCreate routes

Für die Routingfunktionalität wird die Route-Klasse als Standardimplementierung von IRouter zur Verfügung gestellt.Routing provides the Route class as the standard implementation of IRouter. Route verwendet die Syntax für Routenvorlagen, um Muster zu definieren, die dem URL-Pfad zugeordnet werden können, wenn RouteAsync aufgerufen wird.Route uses the route template syntax to define patterns to match against the URL path when RouteAsync is called. Route nutzt dieselbe Routenvorlage zum Generieren einer URL, wenn GetVirtualPath aufgerufen wird.Route uses the same route template to generate a URL when GetVirtualPath is called.

Die meisten Apps erstellen Routen, indem sie MapRoute oder eine ähnliche Erweiterungsmethode aufrufen, die in IRouteBuilder definiert ist.Most apps create routes by calling MapRoute or one of the similar extension methods defined on IRouteBuilder. All diese IRouteBuilder-Erweiterungsmethoden erstellen eine Instanz von Route und fügen diese der Routensammlung hinzu.Any of the IRouteBuilder extension methods create an instance of Route and add it to the route collection.

MapRoute akzeptiert keine Routenhandlerparameter.MapRoute doesn't accept a route handler parameter. Durch MapRoute werden nur Routen hinzugefügt, die vom DefaultHandler verarbeitet werden.MapRoute only adds routes that are handled by the DefaultHandler. Der Standardhandler ist ein IRouter. Möglicherweise verarbeitet der Handler die Anforderung nicht.The default handler is an IRouter, and the handler might not handle the request. Beispielsweise ist ASP.NET Core MVC üblicherweise als Standardhandler konfiguriert, der nur Anforderungen verarbeitet, die mit einem verfügbaren Controller und einer Aktion übereinstimmen.For example, ASP.NET Core MVC is typically configured as a default handler that only handles requests that match an available controller and action. Weitere Informationen zum Routing in MVC finden Sie unter Routing zu Controlleraktionen in ASP.NET Core.To learn more about routing in MVC, see Routing zu Controlleraktionen in ASP.NET Core.

Im folgenden Codebeispiel wird ein MapRoute-Aufruf dargestellt, der von einer typischen ASP.NET Core MVC-Routendefinition verwendet wird: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?}");

Diese Vorlage ordnet einen URL-Pfad zu und extrahiert die Routenwerte.This template matches a URL path and extracts the route values. Beispielsweise generiert der Pfad /Products/Details/17 die folgenden Routenwerte: { controller = Products, action = Details, id = 17 }.For example, the path /Products/Details/17 generates the following route values: { controller = Products, action = Details, id = 17 }.

Routenwerte werden ermittelt, indem der URL-Pfad in Segmente aufgeteilt wird und jedes Segment mit dem Namen des Routenparameters in der Routenvorlage abgeglichen wird.Route values are determined by splitting the URL path into segments and matching each segment with the route parameter name in the route template. Jeder Routenparameter hat einen Namen.Route parameters are named. Die Parameter werden von Klammern { ... } eingeschlossen und dadurch definiert.The parameters defined by enclosing the parameter name in braces { ... }.

Die obige Vorlage kann auch dem URL-Pfad / zugeordnet werden und daraus die Werte { controller = Home, action = Index } generieren.The preceding template could also match the URL path / and produce the values { controller = Home, action = Index }. Dies liegt daran, dass die Routenparameter {controller} und {action} über Standardwerte verfügen und der Routenparameter id optional ist.This occurs because the {controller} and {action} route parameters have default values and the id route parameter is optional. Hinter dem Namen des Routenparameters steht das Gleichheitszeichen (=), auf das der Wert folgt, der als Standardwert für den Parameter definiert wird.An equals sign (=) followed by a value after the route parameter name defines a default value for the parameter. Durch ein Fragezeichen (?) nach dem Namen des Routenparameters wird ein optionaler Parameter definiert.A question mark (?) after the route parameter name defines an optional parameter.

Durch Routenparameter mit einem Standardwert wird immer ein Routenwert erzeugt, wenn eine Übereinstimmung für die Route ermittelt wird.Route parameters with a default value always produce a route value when the route matches. Bei optionalen Parametern wird kein Routenwert generiert, wenn kein entsprechendes URL-Pfadsegment vorhanden ist.Optional parameters don't produce a route value if there is no corresponding URL path segment. Eine ausführliche Beschreibung zu den Szenarios und zur Syntax der Routenvorlage finden Sie unter Referenz zu Routenvorlagen.See the Route template reference section for a thorough description of route template scenarios and syntax.

Im folgenden Beispiel definiert die Routenparameterdefinition {id:int} eine Routeneinschränkung für den Routenparameter 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}");

Durch diese Vorlage wird bei einem Abgleich beispielsweise der URL-Pfad /Products/Details/17, aber nicht /Products/Details/Apples gefunden.This template matches a URL path like /Products/Details/17 but not /Products/Details/Apples. In derartigen Einschränkungen wird IRouteConstraint implementiert, und die Routenwerte werden auf Gültigkeit geprüft.Route constraints implement IRouteConstraint and inspect route values to verify them. Im obigen Beispiel muss sich der Routenwert id in einen Integer konvertieren lassen.In this example, the route value id must be convertible to an integer. Weitere Informationen zu Routeneinschränkungen, die vom Framework bereitgestellt werden, finden Sie in der Referenz zu Routeneinschränkungen.See route-constraint-reference for an explanation of route constraints provided by the framework.

Bei zusätzlichen Überladungen von MapRoute werden Werte für constraints, dataTokens und defaults akzeptiert.Additional overloads of MapRoute accept values for constraints, dataTokens, and defaults. Üblicherweise werden diese Parameter so verwendet, dass ein Objekt eines anonymen Typs übergeben wird, in dem die Eigenschaftsnamen des anonymen Typs mit den Routenparameternamen abgeglichen werden.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.

In den folgenden MapRoute-Beispielen werden identische Routen erstellt: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?}");

Tipp

Für einfache Routen eignet sich die Inline-Syntax zum Definieren von Einschränkungen und Standardwerten.The inline syntax for defining constraints and defaults can be convenient for simple routes. Bestimmte Szenarios wie die Verwendung von Datentoken werden von dieser allerdings nicht unterstützt.However, there are scenarios, such as data tokens, that aren't supported by inline syntax.

Das folgende Beispiel veranschaulicht einige weitere Szenarios:The following example demonstrates a few additional scenarios:

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

Diese Vorlage kann einem URL-Pfad wie /Blog/All-About-Routing/Introduction zugeordnet werden. Sie extrahier die { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }-Werte.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 }. Die Standardroutenwerte für controller und action werden von der Route generiert, obwohl keine entsprechenden Routenparameter in der Vorlage vorhanden sind.The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. Standardwerte können in der Routenvorlage angegeben werden.Default values can be specified in the route template. Der Routenparameter article wird durch ein Sternchen (*) vor dem zugehörigen Namen als Catch-All-Parameter definiert.The article route parameter is defined as a catch-all by the appearance of an asterisk (*) before the route parameter name. So wird der verbleibende Teil des URL-Pfads erfasst, und auch leere Zeichenfolgen können gefunden werden.Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

Im folgenden Beispiel werden Routeneinschränkungen und Datentoken hinzugefügt: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" });

Diese Vorlage kann einem URL-Pfad wie /en-US/Products/5 zugeordnet werden, und die { controller = Products, action = Details, id = 5 }-Werte und { locale = en-US }-Datentoken werden extrahiert.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 }.

Gebietsschemas, Windows-Tokens

Generieren der URL zu einer RoutenklasseRoute class URL generation

Durch die Kombination von mehreren Routenwerten und der zugehörigen Routenvorlage kann die Route-Klasse auch URLs generieren.The Route class can also perform URL generation by combining a set of route values with its route template. Dieser Prozess verläuft umgekehrt zum Abgleich eines URL-Pfads.This is logically the reverse process of matching the URL path.

Tipp

Wenn Sie die URL-Generierung besser nachvollziehen möchten, sollten Sie sich überlegen, welche URL generiert werden soll und wie diese mithilfe der Routenvorlage abgeglichen wird.To better understand URL generation, imagine what URL you want to generate and then think about how a route template would match that URL. Dabei sollten Sie auch darüber nachdenken, welche Werte erstellt werden.What values would be produced? Dieser Vorgang entspricht in etwa der URL-Generierung in der Route-Klasse.This is the rough equivalent of how URL generation works in the Route class.

Im folgenden Beispiel wird eine allgemeine Standardroute für ASP.NET Core-MVC verwendet:The following example uses a general ASP.NET Core MVC default route:

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

Mithilfe der Routenwerte { controller = Products, action = List } wird die URL /Products/List generiert.With the route values { controller = Products, action = List }, the URL /Products/List is generated. Die Routenwerte werden als Ersatz für die entsprechenden Routenparameter verwendet, wodurch ein URL-Pfad erstellt werden kann.The route values are substituted for the corresponding route parameters to form the URL path. Da es sich bei id um einen optionalen Routenparameter handelt, wird die URL erfolgreich ohne einen Wert für id generiert.Since id is an optional route parameter, the URL is successfully generated without a value for id.

Mithilfe der Routenwerte { controller = Home, action = Index } wird die URL / generiert.With the route values { controller = Home, action = Index }, the URL / is generated. Die bereitgestellten Routenwerte entsprechen den Standardwerten, sodass die Segmente, die mit diesen Werten übereinstimmen, problemlos ausgelassen werden können.The provided route values match the default values, and the segments corresponding to the default values are safely omitted.

Mit beiden generierten URLs (/Home/Index und /) und dieser Routendefinition wird ein Roundtrip ausgeführt, und es werden dieselben Routenwerte erstellt, die auch zur Generierung der URL verwendet wurden.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.

Hinweis

Eine auf ASP.NET Core MVC basierende App sollte zur Generierung von URLs die Routingfunktion nicht direkt aufrufen, sondern UrlHelper verwenden.An app using ASP.NET Core MVC should use UrlHelper to generate URLs instead of calling into routing directly.

Weitere Informationen zur Generierung von URLs finden Sie im Abschnitt Referenz zur URL-Generierung.For more information on URL generation, see the Url generation reference section.

Verwenden von RoutingmiddlewareUse routing middleware

Legen Sie das Microsoft.AspNetCore.App-Metapaket in der Projektdatei der App als Verweis fest.Reference the Microsoft.AspNetCore.App metapackage in the app's project file.

Fügen Sie anschließend dem Dienstcontainer in Startup.ConfigureServices die Routingfunktionalität hinzu:Add routing to the service container in Startup.ConfigureServices:

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

Routen müssen in der Startup.Configure-Methode konfiguriert werden.Routes must be configured in the Startup.Configure method. In der Beispiel-App werden die folgenden APIs verwendet: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);

In der folgenden Tabelle werden die Antworten mit den angegebenen URIs aufgelistet:The following table shows the responses with the given URIs.

URIURI AntwortResponse
/package/create/3 Hallo!Hello! Route values: [operation, create], [id, 3]Route values: [operation, create], [id, 3]
/package/track/-3 Hallo!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/-3/ Hallo!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/ The request falls through, no match. (Die Anforderung ist fehlgeschlagen, keine Übereinstimmung.)The request falls through, no match.
GET /hello/Joe Hi, Joe!Hi, Joe!
POST /hello/Joe The request falls through, matches HTTP GET only (Die Anforderung ist fehlgeschlagen, nur für eine HTTP-GET-Anforderung wird eine Übereinstimmung ermittelt)The request falls through, matches HTTP GET only.
GET /hello/Joe/Smith The request falls through, no match. (Die Anforderung ist fehlgeschlagen, keine Übereinstimmung.)The request falls through, no match.

Wenn Sie eine einzelne Route konfigurieren, müssen Sie UseRouter aufrufen und eine IRouter-Instanz übergeben.If you're configuring a single route, call UseRouter passing in an IRouter instance. RouteBuilder muss nicht verwendet werden.You won't need to use RouteBuilder.

Das Framework stellt mehrere Erweiterungsmethoden zum Erstellen von Routen zur Verfügung (RequestDelegateRouteBuilderExtensions):The framework provides a set of extension methods for creating routes (RequestDelegateRouteBuilderExtensions):

Einige der aufgeführten Methoden (z. B. MapGet) erfordern einen RequestDelegate.Some of listed methods, such as MapGet, require a RequestDelegate. RequestDelegate wird als Routenhandler verwendet, wenn der Abgleich für die Route erfolgreich ist.The RequestDelegate is used as the route handler when the route matches. Für andere Erweiterungsmethoden kann eine Middlewarepipeline konfiguriert werden, die als Routenhandler verwendet wird.Other methods in this family allow configuring a middleware pipeline for use as the route handler. Wenn die Map*-Methode einen Handler wie MapRoute nicht akzeptiert, verwendet sie DefaultHandler.If the Map* method doesn't accept a handler, such as MapRoute, it uses the DefaultHandler.

In den Map[Verb]-Methoden werden Einschränkungen verwendet, um die Route auf das HTTP-Verb im Methodennamen zu beschränken.The Map[Verb] methods use constraints to limit the route to the HTTP Verb in the method name. Beispielsweise unter MapGet und MapVerb.For example, see MapGet and MapVerb.

Referenz für RoutenvorlagenRoute template reference

Token in geschweiften Klammern ({ ... }) definieren Routenparameter, die beim Abgleich der Route gebunden werden.Tokens within curly braces ({ ... }) define route parameters that are bound if the route is matched. Sie können in einem Routensegment mehrere Routenparameter definieren, wenn Sie sie durch einen Literalwert trennen.You can define more than one route parameter in a route segment, but they must be separated by a literal value. {controller=Home}{action=Index} ist z.B. keine gültige Route, da sich zwischen {controller} und {action} kein Literalwert befindet.For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. Diese Routenparameter müssen einen Namen besitzen und können zusätzliche Attribute aufweisen.These route parameters must have a name and may have additional attributes specified.

Eine Literalzeichenfolge, die nicht den Routenparametern entspricht (z.B. {id}), muss zusammen mit dem Pfadtrennzeichen / mit dem URL-Text übereinstimmen.Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. Beim Abgleich von Text wird nicht zwischen Groß-/Kleinbuchstaben unterschieden, und die Übereinstimmung basiert auf der decodierten Repräsentation des URL-Pfads.Text matching is case-insensitive and based on the decoded representation of the URLs path. Damit das Trennzeichen ({ oder }) der Routenparameterliteralzeichenfolge bei einem Abgleich gefunden wird, muss es doppelt vorhanden sein ({{ oder }}), was einem Escapezeichen entspricht.To match a literal route parameter delimiter ({ or }), escape the delimiter by repeating the character ({{ or }}).

Bei einem URL-Muster, durch das ein Dateiname mit einer optionalen Erweiterung erfasst werden soll, sind noch weitere Aspekte zu berücksichtigen.URL patterns that attempt to capture a file name with an optional file extension have additional considerations. Dies wird z.B. anhand der Vorlage files/{filename}.{ext?} deutlich.For example, consider the template files/{filename}.{ext?}. Wenn sowohl für filename als auch für ext Werte vorhanden sind, werden beide Werte angegeben.When values for both filename and ext exist, both values are populated. Wenn nur für filename ein Wert in der URL vorhanden ist, wird für die Route eine Zuordnung ermittelt, da der nachstehende Punkt (.) optional ist.If only a value for filename exists in the URL, the route matches because the trailing period (.) is optional. Für die folgenden URLs wird eine Übereinstimmung für die Route ermittelt:The following URLs match this route:

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

Sie können das Sternchen (*) als Präfix für einen Routenparameter verwenden, um eine Bindung zum verbleibenden Teil des URI herzustellen.You can use the asterisk (*) as a prefix to a route parameter to bind to the rest of the URI. Hierbei wird von einem Catch-All-Parameter gesprochen.This is called a catch-all parameter. Durch blog/{*slug} wird beispielsweise jeder URI ermittelt, der mit /blog beginnt und dahinter einen beliebigen Wert aufweist, der dann dem slug-Routenwert zugeordnet wird.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. Durch Catch-All-Parameter können auch leere Zeichenfolgen gefunden werden.Catch-all parameters can also match the empty string.

Der Catch-All-Parameter schützt die entsprechenden Zeichen (Escaping), wenn die Route verwendet wird, um eine URL, einschließlich Pfadtrennzeichen zu generieren (/).The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. Z.B. generiert die Route foo/{*path} mit den Routenwerten { path = "my/path" }``foo/my%2Fpath.For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Beachten Sie den umgekehrten Schrägstrich mit Escapezeichen.Note the escaped forward slash.

Routenparameter können über mehrere Standardwerte verfügen, die nach dem Parameternamen angegeben werden und durch ein Gleichheitszeichen (=) voneinander getrennt werden.Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). Mit {controller=Home} wird beispielsweise Home als Standardwert für controller definiert.For example, {controller=Home} defines Home as the default value for controller. Der Standardwert wird verwendet, wenn kein Wert in der Parameter-URL vorhanden ist.The default value is used if no value is present in the URL for the parameter. Routenparameter sind optional, wenn am Ende des Parameternamens ein Fragezeichen (?) angefügt wird, z. B. id?.Route parameters are made optional by appending a question mark (?) to the end of the parameter name, as in id?. Der Unterschied zwischen optionalen Parametern und Routenparametern mit einem Standardwert besteht darin, dass mithilfe der letzteren immer ein Wert erzeugt wird. Ein optionaler Parameter verfügt demgegenüber nur dann über einen Wert, wenn ein solcher von der Anforderungs-URL bereitgestellt wird.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.

Routenparameter können Einschränkungen aufweisen, die mit dem gebundenen Routenwert der URL übereinstimmen müssen.Route parameters may have constraints that must match the route value bound from the URL. Eine Inline-Einschränkung für einen Routenparameter geben Sie an, indem Sie hinter dem Namen des Routenparameters einen Doppelpunkt (:) und einen Einschränkungsnamen hinzufügen.Adding a colon (:) and constraint name after the route parameter name specifies an inline constraint on a route parameter. Wenn für die Einschränkung Argumente erforderlich sind, werden diese nach dem Einschränkungsnamen in Klammern ((...)) eingeschlossen.If the constraint requires arguments, they're enclosed in parentheses ((...)) after the constraint name. Mehrere Inline-Einschränkungen können festgelegt werden, indem ein weiterer Doppelpunkt (:) und Einschränkungsname hinzugefügt werden.Multiple inline constraints can be specified by appending another colon (:) and constraint name.

Der Einschränkungsname und die Argumente werden dem IInlineConstraintResolver-Dienst übergeben, wodurch eine Instanz von IRouteConstraint für die URL-Verarbeitung erstellt werden kann.The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. In der Routenvorlage blog/{article:minlength(10)} wird beispielsweise die Einschränkung minlength mit dem Argument 10 festgelegt.For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. Weitere Informationen zu Routeneinschränkungen und eine Liste der vom Framework bereitgestellten Einschränkungen finden Sie im Abschnitt Referenz zu Routeneinschränkungen.For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

Die folgende Tabelle enthält Beispielvorlagen für Routen und deren Verhalten.The following table demonstrates example route templates and their behavior.

RoutenvorlageRoute Template Beispiel-URI für ÜbereinstimmungExample Matching URI Der Anforderungs-URI…The request URI…
hello /hello Nur für den Pfad /hello wird eine Übereinstimmung ermittelt.Only matches the single path /hello.
{Page=Home} / Eine Übereinstimmung wird ermittelt, und Page wird auf Home festgelegt.Matches and sets Page to Home.
{Page=Home} /Contact Eine Übereinstimmung wird ermittelt, und Page wird auf Contact festgelegt.Matches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List Stimmt mit dem Products-Controller und der List-Aktion überein.Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 Stimmt mit dem Products-Controller und der Details-Aktion (id auf 123 festgelegt) überein.Maps to the Products controller and Details action (id set to 123).
{controller=Home}/{action=Index}/{id?} / Stimmt mit dem Home-Controller und der Index-Aktion überein (id wird ignoriert).Maps to the Home controller and Index method (id is ignored).

Mit Vorlagen lässt sich Routing besonders leicht durchführen.Using a template is generally the simplest approach to routing. Einschränkungen und Standardwerte können auch außerhalb der Routenvorlage angegeben werden.Constraints and defaults can also be specified outside the route template.

Tipp

Wenn Sie die Protokollierung aktivieren, erfahren Sie, wie die integrierten Routingimplementierungen (z.B. Route) Zuordnungen für Anforderungen ermitteln.Enable Logging to see how the built-in routing implementations, such as Route, match requests.

Referenz für RouteneinschränkungenRoute constraint reference

Routeneinschränkungen werden angewendet, wenn eine Übereinstimmung mit der eingehenden URL gefunden wurde und der URL-Pfad in Routenwerten mit Token versehen wird.Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. In der Regel wird mit Routeneinschränkungen der Routenwert der zugehörigen Vorlage geprüft. Dabei wird bestimmt, ob der Wert gültig ist.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. Für einige Routeneinschränkungen werden anstelle des Routenwerts andere Daten verwendet, um zu ermitteln, ob das Routing einer Anforderung möglich ist.Some route constraints use data outside the route value to consider whether the request can be routed. HttpMethodRouteConstraint kann beispielsweise auf der Grundlage des HTTP-Verbs eine Anforderung entweder annehmen oder ablehnen.For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. Einschränkungen werden in Routinganforderungen und bei der Linkgenerierung verwendet.Constraints are used in routing requests and link generation.

Warnung

Verwenden Sie keine Einschränkungen für die Eingabeüberprüfung.Don't use constraints for input validation. Wenn bei der Eingabevalidierung Einschränkungen verwendet werden, lösen ungültige Eingaben den Fehler 404 - Not Found (404 – Nicht gefunden) aus. Stattdessen sollte jedoch der Fehler 400 - Bad Request (400 – Fehlerhafte Anforderung) ausgelöst und mit einer entsprechenden Fehlermeldung angezeigt werden.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. Verwenden Sie Routeneinschränkungen nicht, um Eingaben für eine bestimmte Route zu überprüfen, sondern um ähnlichen Routen zu unterscheiden.Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

In der folgenden Tabelle werden Beispiele für Routeneinschränkungen und deren zu erwartendes Verhalten beschriebe.The following table demonstrates example route constraints and their expected behavior.

Einschränkungconstraint BeispielExample Beispiele für ÜbereinstimmungenExample Matches HinweiseNotes
int {id:int} 123456789, -123456789123456789, -123456789 Für jeden Integer wird eine Übereinstimmung ermittelt.Matches any integer
bool {active:bool} true, FALSEtrue, FALSE Für true oder false wird eine Übereinstimmung ermittelt (keine Unterscheidung zwischen Groß-/Kleinbuchstaben).Matches true or false (case-insensitive)
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm Entspricht einem gültigen DateTime-Wert in der invarianten Kultur.Matches a valid DateTime value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
decimal {price:decimal} 49.99, -1,000.0149.99, -1,000.01 Entspricht einem gültigen decimal-Wert in der invarianten Kultur.Matches a valid decimal value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
double {weight:double} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen double-Wert in der invarianten Kultur.Matches a valid double value in the invariant culture. Siehe vorherige Warnung.See preceding warning.
float {weight:float} 1.234, -1,001.01e81.234, -1,001.01e8 Entspricht einem gültigen float-Wert in der invarianten Kultur.Matches a valid float value in the invariant culture. Siehe vorherige Warnung.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} Für einen gültigen Guid-Wert wird eine Übereinstimmung ermittelt.Matches a valid Guid value
long {ticks:long} 123456789, -123456789123456789, -123456789 Für einen gültigen long-Wert wird eine Übereinstimmung ermittelt.Matches a valid long value
minlength(value) {username:minlength(4)} Rick Die Zeichenfolge muss mindestens eine Länge von 4 Zeichen aufweisen.String must be at least 4 characters
maxlength(value) {filename:maxlength(8)} Richard Die Zeichenfolge darf maximal eine Länge von 8 Zeichen aufweisen.String must be no more than 8 characters
length(length) {filename:length(12)} somefile.txt Die Zeichenfolge muss genau 12 Zeichen aufweisen.String must be exactly 12 characters long
length(min,max) {filename:length(8,16)} somefile.txt Die Zeichenfolge muss mindestens eine Länge von 8 und darf maximal eine Länge von 16 Zeichen aufweisen.String must be at least 8 and no more than 16 characters long
min(value) {age:min(18)} 19 Der Integerwert muss mindestens 18 sein.Integer value must be at least 18
max(value) {age:max(120)} 91 Der Integerwert darf nicht größer als 120 sein.Integer value must be no more than 120
range(min,max) {age:range(18,120)} 91 Der Integerwert muss zwischen 18 und 120 liegen.Integer value must be at least 18 but no more than 120
alpha {name:alpha} Rick Die Zeichenfolge muss aus mindestens einem alphabetische Zeichen bestehen (a-z, keine Unterscheidung zwischen Groß-/Kleinbuchstaben).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 Die Zeichenfolge muss dem regulären Ausdruck entsprechen (siehe Tipp zum Definieren eines regulären Ausdrucks)String must match the regular expression (see tips about defining a regular expression)
required {name:required} Rick Hierdurch wird erzwungen, dass ein Wert, der kein Parameter ist, für die URL-Generierung vorhanden sein muss.Used to enforce that a non-parameter value is present during URL generation

Auf einen einzelnen Parameter können mehrere durch Doppelpunkte getrennte Einschränkungen angewendet werden.Multiple, colon-delimited constraints can be applied to a single parameter. Durch die folgende Einschränkung wird ein Parameter beispielsweise auf einen Integerwert größer oder gleich 1 beschränkt: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) { }

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet.Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.These constraints assume that the URL is non-localizable. Die vom Framework bereitgestellten Routeneinschränkungen ändern nicht die Werte, die in Routenwerten gespeichert sind.The framework-provided route constraints don't modify the values stored in route values. Alle Routenwerte, die aus der URL analysiert werden, werden als Zeichenfolgen gespeichert.All route values parsed from the URL are stored as strings. Durch die float-Einschränkung wird beispielsweise versucht, den Routenwert in einen Gleitkommawert zu konvertieren. Mit dem konvertierten Wert wird allerdings nur überprüft, ob eine Umwandlung überhaupt möglich ist.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.

Reguläre AusdrückeRegular expressions

Im ASP.NET Core-Framework wird dem Konstruktor für reguläre Ausdrücke RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant hinzugefügt.The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. Eine Beschreibung dieser Member finden Sie unter RegexOptions.See RegexOptions for a description of these members.

In regulären Ausdrücken werden Trennzeichen und Token verwendet, die auch beim Routing und in der Programmiersprache C# in ähnlicher Weise verwendet werden.Regular expressions use delimiters and tokens similar to those used by Routing and the C# language. Token, die reguläre Ausdrücke enthalten, müssen mit einem Escapezeichen versehen werden.Regular expression tokens must be escaped. Wenn Sie den regulären Ausdruck ^\d{3}-\d{2}-\d{4}$ für das Routing verwenden möchten, muss der Ausdruck \-Zeichen (einzelner Schrägstrich) enthalten, die in der C#-Quelldatei in der Zeichenfolge als \\-Zeichen (doppelter Schrägstrich) angegeben sind, damit die \-Zeichenfolge mit einem Escapezeichen versehen wird. Dies ist nicht erforderlich, wenn ausführliche Zeichenfolgenliterale verwendet werden.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). Wenn Sie Trennzeichen für Routenparameter mit Escapezeichen versehen möchten ({, }, [, ]), geben Sie jedes Zeichen im Ausdruck doppelt ein ({{, }, [[, ]]).To escape routing parameter delimiter characters ({, }, [, ]), double the characters in the expression ({{, }, [[, ]]). In der folgenden Tabelle werden reguläre Ausdrücke und Ausdrücke aufgeführt, die mit Escapezeichen versehen sind.The following table shows a regular expression and the escaped version.

Regulärer AusdruckRegular Expression Mit Escapezeichen versehener regulärer AusdruckEscaped Regular Expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Beim Routing verwendete reguläre Ausdrücke beginnen oft mit einem Caretzeichen (^) und stellen die Startposition der Zeichenfolge dar.Regular expressions used in routing often start with the caret (^) character and match starting position of the string. Die Ausdrücke enden häufig mit einem Dollarzeichen ($) und stellen das Ende der Zeichenfolge dar.The expressions often end with the dollar sign ($) character and match end of the string. Mit den Zeichen ^ und $ wird sichergestellt, dass der reguläre Ausdruck mit dem vollständigen Routenparameterwert übereinstimmt.The ^ and $ characters ensure that the regular expression match the entire route parameter value. Ohne die Zeichen ^ und $ werden mit dem regulären Ausdruck alle Teilzeichenfolgen ermittelt, was häufig nicht gewünscht ist.Without the ^ and $ characters, the regular expression match any substring within the string, which is often undesirable. In der folgenden Tabelle finden Sie Beispiele für reguläre Ausdrücke. Außerdem wird erklärt, warum ein Abgleich erfolgreich ist oder fehlschlägt.The following table provides examples and explains why they match or fail to match.

expressionExpression ZeichenfolgeString MatchMatch KommentarComment
[a-z]{2} hellohello JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} 123abc456123abc456 JaYes Teilzeichenfolge stimmt übereinSubstring matches
[a-z]{2} mzmz JaYes Ausdruck stimmt übereinMatches expression
[a-z]{2} MZMZ JaYes keine Unterscheidung zwischen Groß-/KleinbuchstabenNot case sensitive
^[a-z]{2}$ hellohello NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above
^[a-z]{2}$ 123abc456123abc456 NeinNo siehe Erläuterungen zu ^ und $ obenSee ^ and $ above

Weitere Informationen zur Syntax von regulären Ausdrücken finden Sie unter Sprachelemente für reguläre Ausdrücke – Kurzübersicht.For more information on regular expression syntax, see .NET Framework Regular Expressions.

Einen regulären Ausdruck können Sie verwenden, um einen Parameter auf zulässige Werte einzuschränken.To constrain a parameter to a known set of possible values, use a regular expression. Mit {action:regex(^(list|get|create)$)} werden beispielsweise für den action-Routenwert nur die Werte list, get oder create abgeglichen.For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. Wenn die Zeichenfolge ^(list|get|create)$ dem Einschränkungswörterbuch übergeben wird, führt dies zum gleichen Ergebnis.If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. Auch Einschränkungen, die dem zugehörigen Wörterbuch hinzugefügt werden und mit keiner vorgegebenen Einschränkung übereinstimmen , werden als reguläre Ausdrücke behandelt. Dies gilt allerdings nicht für Inline-Einschränkungen in einer Vorlage.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.

Benutzerdefinierte RouteneinschränkungenCustom Route Constraints

Zusätzlich zu den integrierten Routeneinschränkungen können benutzerdefinierte Routeneinschränkungen durch Implementierung der IRouteConstraint-Schnittstelle erstellt werden.In addition to the built-in route constraints, custom route constraints can be created by implementing the IRouteConstraint interface. Die IRouteConstraint-Schnittstelle enthält eine einzelne Methode, Match, die true zurückgibt, wenn die Einschränkung erfüllt wird, und andernfalls false.The IRouteConstraint interface contains a single method, Match, which returns true if the constraint is satisfied and false otherwise.

Zum Verwenden einer benutzerdefinierten IRouteConstraint muss der Routeneinschränkungstyp bei der ConstraintMap der App im Dienstcontainer der App registriert werden.To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the app's service container. Eine ConstraintMap ist ein Wörterbuch, das Routeneinschränkungsschlüssel IRouteConstraint-Implementierungen zuordnet, die diese Einschränkungen überprüfen.A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. Die ConstraintMap einer App kann in Startup.ConfigureServices entweder als Teil eines services.AddRouting-Aufrufs oder durch direktes Konfigurieren von RouteOptions mit services.Configure<RouteOptions> aktualisiert werden.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>. Zum Beispiel:For example:

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

Die Einschränkung kann dann auf die übliche Weise mit dem bei der Registrierung des Einschränkungstyps angegebenen Namen auf Routen angewendet werden.The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. Zum Beispiel:For example:

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

Referenz für URL-GenerierungURL generation reference

Im folgenden Beispiel wird gezeigt, wie Sie einen Link zu einer Route unter Berücksichtigung eines vorhandenen Wörterbuchs mit Routenwerten und einer RouteCollection erstellen.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/>");
});

Die VirtualPath-Eigenschaft, die am Ende des obigen Beispiels erstellt wird, hat den Wert /package/create/123.The VirtualPath generated at the end of the preceding sample is /package/create/123. Das Wörterbuch stellt die Routenwerte von operation und id aus der Vorlage „Track Package Route“ (package/{operation}/{id}) bereit.The dictionary supplies the operation and id route values of the "Track Package Route" template, package/{operation}/{id}. Weitere Informationen finden Sie im Beispielcode im Abschnitt Verwenden von Routingmiddleware oder in der Beispiel-App.For details, see the sample code in the Use Routing Middleware section or the sample app.

Der zweite Parameter für den VirtualPathContext-Konstruktor ist eine Auflistung von Umgebungswerten.The second parameter to the VirtualPathContext constructor is a collection of ambient values. Mit diesen lässt sich leicht die Anzahl der Werte einschränken, die ein Entwickler innerhalb eines Anforderungskontexts angeben muss.Ambient values are convenient to use because they limit the number of values a developer must specify within a request context. Die aktuellen Routenwerte der aktuellen Anforderung werden bei der Linkgenerierung als Umgebungswerte behandelt.The current route values of the current request are considered ambient values for link generation. In einer ASP.NET Core-MVC-App müssen Sie innerhalb der About-Aktion von HomeController nicht den Controllerroutenwert angeben, um eine Verknüpfung mit der Index-Aktion herzustellen, da der Umgebungswert von Home verwendet wird.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.

Umgebungswerte, die mit keinem Parameter übereinstimmen, werden ignoriert.Ambient values that don't match a parameter are ignored. Außerdem werden Umgebungswerte ignoriert, wenn ein explizit angegebener Wert den betreffenden Umgebungswert außer Kraft setzt.Ambient values are also ignored when an explicitly provided value overrides the ambient value. Der Abgleich in der URL wird von links nach rechts ausgeführt.Matching occurs from left to right in the URL.

Explizit bereitgestellte Werte, für die keine Übereinstimmungen mit einem Routensegment ermittelt werden, werden der Abfragezeichenfolge hinzugefügt.Values explicitly provided but that don't match a segment of the route are added to the query string. In der folgenden Tabelle werden die Ergebnisse dargestellt, die aus der Verwendung der Routenvorlage {controller}/{action}/{id?} hervorgehen:The following table shows the result when using the route template {controller}/{action}/{id?}.

UmgebungswerteAmbient Values Explizite WerteExplicit Values ErgebnisResult
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

Wenn eine Route über einen Standardwert verfügt, der keinem Parameter entspricht, und dieser Wert explizit bereitgestellt wird, muss er dem Standardwert entsprechen: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" });

Für diese Route wird nur dann ein Link generiert, wenn die übereinstimmenden Werte für controller und action bereitgestellt werden.Link generation only generates a link for this route when the matching values for controller and action are provided.

Komplexe SegmenteComplex segments

Komplexe Segmente (z.B. [Route("/x{token}y")]) werden von rechts nach links auf eine nicht gierige Weise durch entsprechende Literale verarbeitet.Complex segments (for example [Route("/x{token}y")]) are processed by matching up literals from right to left in a non-greedy way. Unter diesem Code finden Sie eine ausführliche Erklärung für das Abgleichen komplexer Segmente.See this code for a detailed explanation of how complex segments are matched. Das Codebeispiel wird von ASP.NET Core nicht verwendet, aber es bietet eine gute Erklärung komplexer Segmente.The code sample is not used by ASP.NET Core, but it provides a good explanation of complex segments.