Freigeben über


ASP.NET-Routing

Aktualisiert: November 2007

Mit ASP.NET-Routing können Sie URLs verwenden, die nicht bestimmten Dateien auf einer Website zugeordnet sein müssen. Da die URL keiner Datei zugeordnet sein muss, können Sie URLs in einer Webanwendung verwenden, die die Benutzeraktion beschreiben und daher verständlicher für die Benutzer sind.

In einer ASP.NET-Anwendung, die kein Routing verwendet, wird eine eingehende Anforderung für eine URL in der Regel einer physischen Datei auf der Festplatte zugeordnet, z. B. einer ASPX-Datei. Eine Anforderung für https://server/application/Products.aspx?id=4 wird z. B. der Datei Products.aspx zugeordnet, die Code und Markup zum Rendern einer Antwort an den Browser enthält. Die Webseite verwendet den Abfragezeichenfolgenwert id=4, um zu ermitteln, welche Art von Inhalt angezeigt werden soll. Der Wert hat jedoch wahrscheinlich keine Bedeutung für den Benutzer.

In ASP.NET-Routing definieren Sie URL-Muster, die Platzhalter für Werte enthalten, die verwendet werden, wenn Sie URL-Anforderungen behandeln. Zur Laufzeit werden die Teile der URL, die dem Anwendungsnamen folgen, anhand eines von Ihnen definierten URL-Musters in diskrete Werte aufgelöst. Beispiel: In der Anforderung für https://server/application/Products/show/beverages kann der Routingparser die Werte Products, show und beverages an einen Handler für die Anforderung übergeben. In einer Anforderung, die nicht durch das URL-Routing verwaltet wird, wird das /Products/show/beverages-Fragment dagegen als Pfad einer Datei in der Anwendung interpretiert.

Sie können die URL-Muster auch verwenden, um URLs, die den Routen entsprechen, programmgesteuert zu erstellen. Dadurch können Sie die Logik zum Erstellen von Hyperlinks in der ASP.NET-Anwendung zentralisieren.

ASP.NET-Routing vs. Überschreiben von URLs

ASP.NET-Routing unterscheidet sich von anderen Verfahren zum Überschreiben von URLs. Das Überschreiben von URLs verarbeitet eingehende Anforderungen, indem die URL geändert wird, bevor die Anforderung an die Webseite gesendet wird. Zum Beispiel könnte eine Anwendung, die das Überschreiben von URLs verwendet, eine URL von /Products/Widgets/ in /Products.aspx?id=4 ändern. Ebenso gibt es beim Überschreiben von URLs in der Regel keine API zum Erstellen von URLs, die auf Ihren Mustern basieren. Wenn Sie beim Überschreiben von URLs ein URL-Muster ändern, müssen Sie alle Hyperlinks, die die ursprüngliche URL enthalten, manuell aktualisieren.

Mit ASP.NET-Routing wird die URL nicht geändert, wenn eine eingehende Anforderung verarbeitet wird, da das Routing Werte aus der URL extrahieren kann. Wenn Sie eine URL erstellen müssen, übergeben Sie Parameterwerte in eine Methode, die die URL für Sie generiert. Um das URL-Muster zu ändern, ändern Sie es an einem Speicherort. Alle Links, die Sie in der Anwendung erstellen und die auf diesem Muster basieren, verwenden automatisch das neue Muster.

Definieren von URL-Routen

Die URL-Muster, die Sie definieren, werden als Routen bezeichnet. In einer Route geben Sie Platzhalter an, die Werten zugeordnet werden, die aus der URL-Anforderung aufgelöst werden. Sie können auch konstante Werte angeben, die für entsprechende URL-Anforderungen verwendet werden.

In einer Route definieren Sie Platzhalter (die als URL-Parameter bezeichnet werden), indem Sie sie in geschweifte Klammern ( { und } ) einschließen. Das /-Zeichen wird als Trennzeichen interpretiert, wenn die URL analysiert wird. Informationen in der Routendefinition, die kein Trennzeichen sind und nicht in geschweiften Klammern stehen, werden als konstanter Wert behandelt. Werte, die zwischen den Trennzeichen extrahiert werden, werden Platzhaltern zugewiesen.

Sie können mehrere Platzhalter zwischen Trennzeichen definieren, diese müssen jedoch durch einen konstanten Wert getrennt werden. Zum Beispiel ist {language}-{country}/{action} ein gültiges Routenmuster. {language}{country}/{action} ist jedoch kein gültiges Muster, da weder eine Konstante noch ein Trennzeichen zwischen den Platzhaltern vorhanden ist. Daher kann das Routing nicht ermitteln, wo der Wert für den language-Platzhalter vom Wert für den country-Platzhalter getrennt werden soll.

Die folgende Tabelle zeigt gültige Routenmuster und Beispiele für URL-Anforderungen, die mit diesen Mustern übereinstimmen.

Routendefinition

Beispiel für passende URL

{controller}/{action}/{id}

/Products/show/beverages

{table}/Details.aspx

/Products/Details.aspx

blog/{action}/{entry}

/blog/show/123

{reporttype}/{year}/{month}/{day}

/sales/2008/1/5

{locale}/{action}

/en-US/show

{language}-{country}/{action}

/en-US/show

Normalerweise fügen Sie Routen in einer Methode hinzu, die aus dem Handler für das Application_Start-Ereignis in der Datei Global.asax aufgerufen wird. Durch diese Vorgehensweise ist gewährleistet, dass die Routen beim Start der Anwendung verfügbar sind. Außerdem können Sie dadurch die Methode direkt aufrufen, wenn Sie den Komponententest für die Anwendung durchführen. Wenn Sie eine Methode beim Komponententest der Anwendung direkt aufrufen möchten, muss die Methode, die die Routen registriert, statisch sein (Shared in Visual Basic) und einen RouteCollection-Parameter enthalten.

Sie fügen Routen hinzu, indem Sie diese der statischen Routes-Eigenschaft der RouteTable-Klasse hinzufügen. Die Routes-Eigenschaft ist einRouteCollection-Objekt, das alle Routen für die ASP.NET-Anwendung speichert. Das folgende Beispiel zeigt Code aus einer Datei Global.asax, die ein Route-Objekt hinzufügt, das zwei URL-Parameter mit der Bezeichnung action und categoryName definiert.

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    RegisterRoutes(RouteTable.Routes)
End Sub

Shared Sub RegisterRoutes(routes As RouteCollection)
    Dim urlPattern As String
    Dim categoryRoute As Route

    urlPattern = "Category/{action}/{categoryName}"
    categoryRoute = New Route(urlPattern, New CategoryRouteHandler)

    routes.Add(categoryRoute)
End Sub
protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route
    (
         "Category/{action}/{categoryName}"
         , new CategoryRouteHandler()
    ));
}

Festlegen von Standardwerten für Routenparameter

Wenn Sie eine Route definieren, können Sie einen Standardwert für einen Parameter zuweisen. Der Standardwert wird verwendet, wenn ein Wert für diesen Parameter nicht in der URL enthalten ist. Sie legen Standardwerte für eine Route fest, indem Sie der Defaults-Eigenschaft der Route-Klasse ein Wörterbuch zuweisen. Im folgenden Beispiel wird eine Route mit Standardwerten veranschaulicht.

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    RegisterRoutes(RouteTable.Routes)
End Sub

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    Dim urlPattern As String
    Dim categoryRoute As Route

    urlPattern = "Category/{action}/{categoryName}"
    categoryRoute = New Route(urlPattern, New CategoryRouteHandler)
    categoryRoute.Defaults = New RouteValueDictionary(New With _
        {.categoryName = "food", _
         .action = "show"} )

    routes.Add(categoryRoute)
End Sub
void Application_Start(object sender, EventArgs e) 
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Add(new Route
  (
     "Category/{action}/{categoryName}"
          new CategoryRouteHandler()
  )
    {
       Defaults = new RouteValueDictionary 
           {{"categoryName", "food"}, {"action", "show"}}
     }
  );
}

Wenn ASP.NET-Routing eine URL-Anforderung behandelt, führt die im Beispiel dargestellte Routendefinition (mit den Standardwerten food für categoryName und show für action) zu den in der folgenden Tabelle aufgeführten Ergebnissen.

URL

Parameterwerte

/Category

action = "show" (Standardwert)

categoryName = "food" (Standardwert)

/Category/add

action = "add"

categoryName = "food" (Standardwert)

/Category/add/beverages

action = "add"

categoryName= "beverages"

Verarbeiten einer variablen Anzahl von Segmenten

Manchmal müssen Sie URL-Anforderungen behandeln, die eine variable Anzahl an URL-Segmenten enthalten. Wenn Sie eine Route definieren, können Sie angeben, dass der letzte Parameter mit dem Rest der URL übereinstimmen soll, indem Sie den Parameter mit einem Sternchen (*) kennzeichnen. Dies wird dann als Catch-All-Parameter (Sammelparameter) bezeichnet. Eine Route mit einem Catch-All-Parameter stimmt auch mit URLs überein, die keine Werte für den letzten Parameter enthalten. Im folgenden Beispiel ist ein Routenmuster dargestellt, das mit einer unbekannten Anzahl an Segmenten übereinstimmt.

query/{queryname}/{*queryvalues}

Wenn ASP.NET-Routing eine URL-Anforderung behandelt, führt die im Beispiel dargestellte Routendefinition zu den in der folgenden Tabelle aufgeführten Ergebnissen.

URL

Parameterwerte

/query/select/bikes/onsale

queryname = "select"

queryvalues = "bikes/onsale"

/query/select/bikes

queryname = "select"

queryvalues = "bikes"

/query/select

queryname = "select"

queryvalues = Empty string

Hinzufügen von Einschränkungen zu Routen

Neben dem Abgleichen einer URL-Anforderung mit einer Routendefinition anhand der Anzahl der Parameter in der URL können Sie angeben, dass Werte in den Parametern bestimmte Einschränkungen erfüllen. Wenn eine URL Werte enthält, die außerhalb der Einschränkungen für eine Route liegen, wird die Route nicht zum Behandeln der Anforderung verwendet. Sie können Einschränkungen hinzufügen, damit die URL-Parameter auf jeden Fall Werte enthalten, die in Ihrer Anwendung funktionieren.

Einschränkungen werden mit regulären Ausdrücken oder mit Objekten definiert, die die IRouteConstraint-Schnittstelle implementieren. Wenn Sie der Routes-Auflistung die Routendefinition hinzufügen, fügen Sie Einschränkungen hinzu, indem Sie ein RouteValueDictionary-Objekt erstellen, das den Überprüfungstest enthält. Anschließend weisen Sie dieses Objekt der Constraints-Eigenschaft zu. Der Schlüssel im Wörterbuch identifiziert den Parameter, für den die Einschränkung gilt. Bei dem Wert im Wörterbuch kann es sich um eine Zeichenfolge handeln, die einen regulären Ausdruck darstellt, oder um ein Objekt, das die IRouteConstraint-Schnittstelle implementiert.

Wenn Sie eine Zeichenfolge angeben, behandelt das Routing die Zeichenfolge als regulären Ausdruck und prüft, ob der Parameterwert gültig ist, indem es die IsMatch-Methode der Regex-Klasse aufruft. Der reguläre Ausdruck wird immer so behandelt, dass nicht zwischen Groß- und Kleinschreibung unterschieden wird. Weitere Informationen hierzu finden Sie unter Reguläre Ausdrücke von .NET Framework.

Wenn Sie ein IRouteConstraint-Objekt bereitstellen, prüft ASP.NET-Routing, ob der Parameterwert gültig ist, indem es die Match-Methode des IRouteConstraint-Objekts aufruft. Die Match-Methode gibt einen booleschen Wert zurück, der angibt, ob der Parameterwert gültig ist.

Das folgende Beispiel zeigt Einschränkungen, die festlegen, welche Werte in den locale-Parameter und den year-Parameter aufgenommen werden können.

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    Dim urlPattern As String
    Dim reportRoute As Route

    urlPattern = "{locale}/{year}"
    reportRoute = New Route(urlPattern, New ReportRouteHandler)
    reportRoute.Constraints = New RouteValueDictionary(New With _
        {.locale = "[a-z]{2}-[a-z]{2}", .year = "\d{4}"})

    routes.Add(reportRoute) 
End Sub
void Application_Start(object sender, EventArgs e) 
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route
    (
      "{locale}/{year}"
         , new ReportRouteHandler()
    )
       {
          Constraints = new RouteValueDictionary 
          {{"locale", "[a-z]{2}-[a-z]{2}"},{year, @"\d{4}"}}
       });
}

Wenn das Routing eine URL-Anforderung behandelt, erstellt die im vorherigen Beispiel dargestellte Routendefinition die in der folgenden Tabelle aufgeführten Ergebnisse.

URL

Result

/en-US

Keine Übereinstimmung. locale und year sind erforderlich.

/en-US/08

Keine Übereinstimmung. Die Einschränkung für year erfordert 4 Ziffern.

/en-US/2008

locale = "en-US"

year = "2008"

Szenarios, in denen kein Routing angewendet wird

Standardmäßig verarbeitet das Routing keine Anforderungen, die einer vorhandenen physischen Datei auf dem Webserver zugeordnet sind. Eine Anforderung für https://server/application/Products/Beverages/Coffee.aspx wird beispielsweise nicht vom Routing verarbeitet, wenn unter Products/Beverages/Coffee.aspx eine physische Datei vorhanden ist. Das Routing verarbeitet die Anforderung nicht, selbst wenn sie mit einem definierten Muster übereinstimmt, z. B. {controller}/{action}/{id}.

Wenn das Routing alle Anforderungen verarbeiten soll, also auch Anforderungen, die auf Dateien zeigen, können Sie das Standardverhalten überschreiben, indem Sie die RouteExistingFiles-Eigenschaft des RouteCollection-Objekts auf true festlegen. Wenn Sie diesen Wert auf true festlegen, werden alle Anforderungen, die mit einem definierten Muster übereinstimmen, durch das Routing verarbeitet.

Sie können auch angeben, dass das Routing bestimmte URL-Anforderungen nicht verarbeiten soll. Sie verhindern, dass das Routing bestimmte Anforderungen behandelt, indem Sie eine Route definieren und angeben, dass die StopRoutingHandler-Klasse zum Behandeln dieses Musters verwendet werden soll. Wenn eine Anforderung von einem StopRoutingHandler-Objekt behandelt wird, blockiert das StopRoutingHandler-Objekt die weitere Verarbeitung von Anforderungen als Route. Stattdessen wird die Anforderung als ASP.NET-Seite, Webdienst oder anderer ASP.NET-Endpunkt verarbeitet. Sie können beispielsweise die folgende Routendefinition hinzufügen, um zu verhindern, dass das Routing Anforderungen für die Datei WebResource.axd behandelt.

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.Add(New Route("{resource}.axd/{*pathInfo}", New StopRouteHandler()))
End Sub
public static void RegisterRoutes(RouteCollection routes)
{
  routes.Add(new Route("{resource}.axd/{*pathInfo}", new StopRouteHandler()));
}

Abgleichen von URLs mit Routen

Wenn das Routing URL-Anforderungen behandelt, versucht es, die URL der Anforderung mit einer Route abzugleichen. Der Abgleich einer URL-Anforderung mit einer Route hängt von allen folgenden Bedingungen ab:

  • Den Routenmustern, die Sie definiert haben, oder den Standardroutenmustern (sofern vorhanden), die in Ihrem Projekttyp enthalten sind.

  • Der Reihenfolge, in der Sie sie der Routes-Auflistung hinzugefügt haben.

  • Allen Standardwerten, die Sie für eine Route angegeben haben.

  • Allen Einschränkungen, die Sie für eine Route angegeben haben.

  • Ob Sie Routing definiert haben, um Anforderungen zu behandeln, die mit einer physischen Datei übereinstimmen.

Um zu vermeiden, dass der falsche Handler eine Anforderung behandelt, müssen Sie alle diese Bedingungen beim Definieren von Routen berücksichtigen. Die Reihenfolge, in der Route-Objekte in der Routes-Auflistung angezeigt werden, ist wichtig. Der Routenabgleich beginnt mit der ersten Route in der Auflistung und geht bis zur letzten Route. Wird eine Übereinstimmung gefunden, werden keine Routen mehr ausgewertet. Im Allgemeinen beginnen Sie beim Hinzufügen von Routen zur Routes-Eigenschaft mit den detailliertesten Routendefinitionen.

Angenommen, Sie fügen Routen mit den folgenden Mustern hinzu:

  • Route 1: {controller}/{action}/{id}

  • Route 2: products/show/{id}

Route 2 behandelt niemals eine Anforderung, da Route 1 zuerst ausgewertet wird und immer mit Anforderungen übereinstimmt, die auch für Route 2 möglich wären. Eine Anforderung für https://server/application/products/show/bikes scheint besser mit Route 2 übereinzustimmen, wird jedoch mit folgenden Werten von Route 1 behandelt:

  • controller = products

  • action = show

  • id = bikes

Wenn ein Parameter in der Anforderung fehlt, werden Standardwerte verwendet. Deshalb können sie dazu führen, dass eine Route mit einer Anforderung übereinstimmt, die Sie nicht erwartet haben. Angenommen, Sie fügen Routen mit den folgenden Mustern hinzu:

  • Route 1: {report}/{year}/{month}, mit Standardwerten für year und month.

  • Route 2: {report}/{year}, mit Standardwert für year.

Route 2 behandelt nie eine Anforderung. Route 1 könnte für einen monatlichen Bericht vorgesehen sein und Route 2 für einen Jahresbericht. Die Standardwerte in Route 1 bedeuten jedoch, dass sie mit jeder Anforderung übereinstimmt, die auch für Route 2 möglich wäre.

Sie können Mehrdeutigkeit in den Mustern vermeiden, indem Sie Konstanten aufnehmen, z. B. annual/{report}/{year} und monthly/{report}/{year}/{month}.

Wenn eine URL mit keinem Route-Objekt übereinstimmt, das in der RouteTable-Auflistung definiert ist, verarbeitet ASP.NET-Routing die Anforderung nicht. Stattdessen wird die Verarbeitung an eine ASP.NET-Seite, einen Webdienst oder einen anderen ASP.NET-Endpunkt übergeben.

Erstellen von URLs aus Routen

Sie können Routen verwenden, um URLs zu generieren, wenn Sie die Logik zum Erstellen von URLs zentralisieren möchten. Sie erstellen eine URL, indem Sie Parameterwerte als Wörterbuch an die GetVirtualPath-Methode des RouteCollection-Objekts übergeben. Die GetVirtualPath-Methode sucht nach der ersten Route im RouteCollection-Objekt, die mit den Parametern im Wörterbuch übereinstimmt. Die übereinstimmende Route wird zum Generieren der URL verwendet. Das folgende Beispiel zeigt eine Routendefinition.

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.Add(New Route( _
      "Category/{action}/{categoryName}", _
      New RouteValueDictionary(New With _
          {.categoryName = "food", _
           .action = "show"}), _
           New CategoryRouteHandler()) )
End Sub
public static void RegisterRoutes(RouteCollection routes)
{
  routes.Add(new Route
  (
     "Category/{action}/{categoryName}"
          new CategoryRouteHandler()
  )
    {
       Defaults = new RouteValueDictionary {{"categoryName", "food"}, 
           {"action", "show"}}
     }
  );
}

Im folgenden Beispiel wird ein Steuerelement dargestellt, das eine URL anhand der Route erstellt.

Dim urlParameters As RouteValueDictionary

urlParameters = New RouteValueDictionary(New With {.categoryName = "beverages", _
        .action = "summarize"})
HyperLink1.href = RouteTable.Routes.GetVirtualPath _
    (context, urlParameters).VirtualPath
HyperLink1.href = RouteTable.Routes.GetVirtualPath
  (context,
  new RouteValueDictionary { 
    { "categoryName", "beverages" }, 
    {"action", "summarize" }}
  ).VirtualPath;

Wenn dieser Code ausgeführt wird, enthält das HyperLink1-Steuerelement den Wert "Category/summarize/beverages" in der href-Eigenschaft.

Wenn Sie eine URL aus einer Route erstellen, können Sie angeben, welche Route verwendet werden soll, indem Sie einen Namen für die Route aufnehmen. Weitere Informationen hierzu finden Sie unter Gewusst wie: Erstellen einer URL aus einer Route.

Siehe auch

Konzepte

Die ASP.NET-Infrastruktur