Freigeben über


UriTemplate und UriTemplateTable

Webentwickler benötigen die Möglichkeit, die Form und das Layout der URIs zu beschreiben, auf die ihre Dienste reagieren. Windows Communication Foundation (WCF) hat zwei neue Klassen hinzugefügt, um Entwicklern die Kontrolle über ihre URIs zu geben. UriTemplate und UriTemplateTable bilden die Basis des URI-basierten Verteilermoduls in WCF. Diese Klassen können auch eigenständig verwendet werden, sodass Entwickler Vorlagen und den URI-Zuordnungsmechanismus nutzen können, ohne einen WCF-Dienst zu implementieren.

Schablonen

Eine Vorlage ist eine Möglichkeit, einen Satz relativer URIs zu beschreiben. Der Satz von URI-Vorlagen in der folgenden Tabelle zeigt, wie ein System, das verschiedene Arten von Wetterinformationen abruft, möglicherweise definiert werden kann.

Daten Schablone
Nationale Prognose Wetter/National
Staatsprognose wetter/{Standort}
Stadtvorhersage Wetter/{Bundesland}/{Stadt}
Aktivitätsprognose Wetter/{Bundesland}/{Stadt}/{Aktivität}

In dieser Tabelle wird eine Reihe strukturell ähnlicher URIs beschrieben. Jeder Eintrag ist eine URI-Vorlage. Die Segmente in geschweiften Klammern beschreiben Variablen. Die Segmente, die nicht in geschweifte Klammern eingefasst sind, beschreiben Literalzeichenfolgen. Die WCF-Vorlagenklassen ermöglichen es einem Entwickler, einen eingehenden URI zu übernehmen, z. B. "/weather/wa/seattle/cycling", und ihn mit einer Vorlage zu matchen, die seine Struktur beschreibt: "/weather/{state}/{city}/{activity}".

UriTemplate

UriTemplate ist eine Klasse, die eine URI-Vorlage kapselt. Der Konstruktor verwendet einen Zeichenfolgenparameter, der die Vorlage definiert. Diese Zeichenfolge enthält die Vorlage im im nächsten Abschnitt beschriebenen Format. Die UriTemplate Klasse stellt Methoden bereit, mit denen Sie einen eingehenden URI mit einer Vorlage abgleichen, einen URI aus einer Vorlage generieren, eine Sammlung von Variablennamen abrufen, die in der Vorlage verwendet werden, bestimmen, ob zwei Vorlagen gleichwertig sind, und die Zeichenfolge der Vorlage zurückgeben.

Match(Uri, Uri) übernimmt eine Basisadresse und einen Kandidaten-URI und versucht, den URI mit der Vorlage abzugleichen. Wenn die Zuordnung erfolgreich ist, wird eine UriTemplateMatch-Instanz zurückgegeben. Das UriTemplateMatch-Objekt enthält einen Basis-URI, den Kandidaten-URI, eine Namens-/Wertauflistung der Abfrageparameter, ein Array der relativen Pfadsegmente, eine Namens-/Wertauflistung von Variablen, die bei der Übereinstimmung verwendet wurden, die UriTemplate-Instanz, die zur Durchführung der Übereinstimmung verwendet wird, eine Zeichenfolge, die einen nicht übereinstimmenden Teil des Kandidaten-URI enthält (verwendet, wenn die Vorlage über eine Wildcard verfügt), und ein Objekt, das der Vorlage zugeordnet ist.

Hinweis

Die UriTemplate Klasse ignoriert das Schema und die Portnummer beim Abgleichen eines Kandidaten-URI mit einer Vorlage.

Es gibt zwei Methoden, mit denen Sie einen URI aus einer Vorlage generieren können, BindByName(Uri, NameValueCollection) und BindByPosition(Uri, String[]). BindByName(Uri, NameValueCollection) akzeptiert eine Basisadresse und eine Namens-/Wertauflistung von Parametern. Diese Parameter werden durch Variablen ersetzt, wenn die Vorlage gebunden ist. BindByPosition(Uri, String[]) nimmt die Namen/Wert-Paare an und ersetzt sie von links nach rechts.

ToString() gibt die Vorlagenzeichenfolge zurück.

Die PathSegmentVariableNames Eigenschaft enthält eine Auflistung der Namen der Variablen, die in Pfadsegmenten in der Vorlagenzeichenfolge verwendet werden.

IsEquivalentTo(UriTemplate) verwendet einen UriTemplate Parameter und gibt einen booleschen Wert zurück, der angibt, ob die beiden Vorlagen gleichwertig sind. Weitere Informationen finden Sie im Abschnitt "Template Equivalence" weiter unten in diesem Thema.

UriTemplate ist für die Arbeit mit jedem URI-Schema konzipiert, das der HTTP-URI-Grammatik entspricht. Im Folgenden sind Beispiele für unterstützte URI-Schemas aufgeführt.

  • http://

  • https://

  • net.tcp://

  • net.pipe://

  • sb://

Schemas wie file:// und urn:// entsprechen nicht der HTTP-URI-Grammatik und verursachen unvorhersehbare Ergebnisse, wenn sie mit URI-Vorlagen verwendet werden.

Vorlagenzeichenfolgen-Syntax

Eine Vorlage enthält drei Teile: einen Pfad, eine optionale Abfrage und ein optionales Fragment. Ein Beispiel finden Sie in der folgenden Vorlage:

"/weather/{state}/{city}?forecast={length)#frag1

Der Pfad besteht aus "/weather/{state}/{city}", die Abfrage besteht aus "?forecast={length}", und das Fragment besteht aus "#frag1".

Führende und nachstehende Schrägstriche sind im Pfadausdruck optional. Sowohl die Abfrage- als auch die Fragmentausdrücke können vollständig weggelassen werden. Ein Pfad besteht aus einer Reihe von Segmenten, die durch '/' getrennt sind, jedes Segment kann einen Literalwert, einen Variablennamen (geschrieben in {curly braces}) oder einen Wildcard (geschrieben als '*') aufweisen. In der vorherigen Vorlage ist das Segment "\wetter\" ein Literalwert, während "{state}" und "{city}" Variablen sind. Variablen nehmen ihren Namen aus dem Inhalt ihrer geschweiften Klammern und können später durch einen konkreten Wert ersetzt werden, um einen geschlossenen URI zu erstellen. Der Wildcard ist optional, kann aber nur am Ende des URI angezeigt werden, wo er logisch mit "dem Rest des Pfads" übereinstimmt.

Wenn vorhanden, gibt der Abfrageausdruck eine Reihe nicht sortierter Name-Wert-Paare an, die durch "&" getrennt sind. Elemente des Abfrageausdrucks können Literalpaare (x=2) oder ein Variablenpaar (x={var}) sein. Nur die rechte Seite der Abfrage kann einen variablen Ausdruck enthalten. ({someName} = {someValue} ist nicht zulässig. Ungepaarte Werte (?x) sind nicht zulässig. Es gibt keinen Unterschied zwischen einem leeren Abfrageausdruck und einem Abfrageausdruck, der nur aus einem einzigen '?' besteht. (beide bedeuten "beliebige Abfrage").

Der Fragmentausdruck kann aus einem Literalwert bestehen, es sind keine Variablen zulässig.

Alle Vorlagenvariablennamen innerhalb einer Vorlagenzeichenfolge müssen eindeutig sein. Bei Namen von Vorlagenvariablen wird die Groß- und Kleinschreibung nicht berücksichtigt.

Beispiele für gültige Vorlagenzeichenfolgen:

  • ""

  • "/Schuh"

  • "/Schuh/*"

  • "{Schuh}/Boot"

  • "{shoe}/{boat}/bed/{quilt}"

  • "shoe/{boat}"

  • "shoe/{boat}/*"

  • "Schuh/Boot?x=2"

  • "shoe/{boat}?x={bed}"

  • "schuh/{boat}?x={bed}&y=band"

  • "?x={shoe}"

  • "schuh?x=3&y={var}

Beispiele für ungültige Vorlagenzeichenfolgen:

  • "{shoe}/{SHOE}/x=2" - Doppelte Variablennamen.

  • "{shoe}/boat/?bed={shoe}" - Doppelte Variablennamen.

  • "?x=2&x=3" – Name/Wert-Paare innerhalb einer Abfragezeichenfolge müssen eindeutig sein, auch wenn sie Literale sind.

  • "?x=2&" – Abfragezeichenfolge ist falsch formatiert.

  • "?2&x={shoe}" – Abfragezeichenfolge muss Name-Wert-Paar sein.

  • "?y=2&&X=3" – Die Abfragezeichenfolge muss Namenswertpaare sein, Namen können nicht mit '&' beginnen.

Segmente eines zusammengesetzten Pfads

Zusammengesetzte Pfadsegmente ermöglichen es einem einzelnen URI-Pfadsegment, mehrere Variablen sowie Variablen in Kombination mit Literalen zu enthalten. Im Folgenden sind Beispiele für gültige Verbundpfadsegmente aufgeführt.

  • /Dateiname.{Erw.}/

  • /{filename}.jpg/

  • /{filename}. {ext}/

  • /{a}.{b}Literalwert{c}({d})/

Im Folgenden sind Beispiele für ungültige Pfadsegmente aufgeführt.

  • /{} - Variablen müssen benannt werden.

  • /{Schuh}{Boot} – Variablen müssen durch einen Literalwert getrennt werden.

Zuordnung und zusammengesetzte Pfadsegmente

Zusammengesetzte Pfadsegmente ermöglichen es Ihnen, eine UriTemplate zu definieren, die mehrere Variablen innerhalb eines einzelnen Pfadsegments enthält. Beispiel: In der folgenden Vorlagenzeichenfolge: "Adressen/{state}. {city}" zwei Variablen (Bundesland und Stadt) werden innerhalb desselben Segments definiert. Diese Vorlage würde mit einer URL wie http://example.com/Washington.Redmond übereinstimmen, aber auch mit einer URL wie http://example.com/Washington.Redmond.Microsoft. In letzterem Fall enthält die Zustandsvariable "Washington", und die Stadtvariable enthält "Redmond.Microsoft". In diesem Fall entspricht jeder Text (mit Ausnahme von '/') der {city}-Variablen. Wenn Sie eine Vorlage benötigen, die nicht mit dem Text "extra" übereinstimmt, platzieren Sie die Variable in einem separaten Vorlagensegment, z. B. "Adressen/{state}/{city}".

Benannte Platzhaltersegmente

Ein benanntes Wildcardsegment ist ein beliebiges Pfadvariablensegment, dessen Variablenname mit dem Wildcardzeichen '*' beginnt. Die folgende Vorlagenzeichenfolge enthält ein benanntes Platzhaltersegment mit dem Namen "Schuh".

"literal/{*shoe}"

Wildcardsegmente müssen den folgenden Regeln entsprechen:

  • Es kann höchstens ein benanntes Wildcardsegment für jede Vorlagenzeichenfolge geben.

  • Ein benanntes Platzhaltersegment muss sich im am weitesten rechts stehenden Segment des Pfads befinden.

  • Ein benanntes Wildcardsegment kann nicht mit einem anonymen Wildcardsegment innerhalb derselben Vorlagenzeichenfolge koexistieren.

  • Der Name eines benannten Platzhaltersegments muss eindeutig sein.

  • Benannte Wildcardsegmente können keine Standardwerte aufweisen.

  • Benannte Wildcardsegmente können nicht mit "/" enden.

Standardwerte für Variablen

Mit Standardvariablenwerten können Sie Standardwerte für Variablen innerhalb einer Vorlage angeben. Standardvariablen können entweder mit den geschweiften Klammern angegeben werden, die die Variable deklarieren, oder als eine Auflistung, die an den UriTemplate-Konstruktor übergeben wird. Die folgende Vorlage zeigt zwei Möglichkeiten zum Angeben von UriTemplate Variablen mit Standardwerten.

UriTemplate t = new UriTemplate("/test/{a=1}/{b=5}");  

Diese Vorlage deklariert eine Variable namens a mit einem Standardwert 1 und eine Variable namens b mit einem Standardwert 5.

Hinweis

Nur Pfadsegmentvariablen dürfen Standardwerte aufweisen. Abfragezeichenfolgenvariablen, zusammengesetzte Segmentvariablen und benannte Wildcardvariablen dürfen keine Standardwerte aufweisen.

Der folgende Code zeigt, wie Die Standardvariablenwerte beim Abgleichen eines Kandidaten-URI behandelt werden.

Uri baseAddress = new Uri("http://localhost:8000/");

UriTemplate t = new UriTemplate("/{state=WA}/{city=Redmond}/", true);
Uri candidate = new Uri("http://localhost:8000/OR");

UriTemplateMatch m1 = t.Match(baseAddress, candidate);

Console.WriteLine($"Template: {t}");
Console.WriteLine($"Candidate URI: {candidate}");

// Display contents of BoundVariables
Console.WriteLine("BoundVariables:");
foreach (string key in m1.BoundVariables.AllKeys)
{
    Console.WriteLine($"\t{key}={m1.BoundVariables[key]}");
}
// The output of the above code is  
// Template: /{state=WA}/{city=Redmond}/
// Candidate URI: http://localhost:8000/OR
// BoundVariables:
//         STATE=OR
//         CITY=Redmond

Hinweis

Ein URI wie http://localhost:8000/// stimmt nicht mit der Vorlage überein, die im vorherigen Code angegeben ist, jedoch stimmt ein URI wie http://localhost:8000/ überein.

Der folgende Code zeigt, wie Die Standardvariablenwerte beim Erstellen eines URI mit einer Vorlage behandelt werden.

Uri baseAddress = new Uri("http://localhost:8000/");  
Dictionary<string,string> defVals = new Dictionary<string,string> {{"a","1"}, {"b", "5"}};  
UriTemplate t = new UriTemplate("/test/{a}/{b}", defVals);  
NameValueCollection vals = new NameValueCollection();  
vals.Add("a", "10");  
  
Uri boundUri = t.BindByName(baseAddress, vals);  
Console.WriteLine("BaseAddress: {0}", baseAddress);  
Console.WriteLine("Template: {0}", t.ToString());  
  
Console.WriteLine("Values: ");  
foreach (string key in vals.AllKeys)  
{  
    Console.WriteLine("\tKey = {0}, Value = {1}", key, vals[key]);  
}  
Console.WriteLine("Bound URI: {0}", boundUri);  
  
// The output of the preceding code is  
// BaseAddress: http://localhost:8000/  
// Template: /test/{a}/{b}  
// Values:  
//     Key = a, Value = 10  
// Bound URI: http://localhost:8000/test/10/5  

Wenn eine Variable einen Standardwert erhält, null gibt es einige zusätzliche Einschränkungen. Eine Variable kann einen Standardwert von null haben, wenn die Variable im rechten Abschnitt der Vorlagenzeichenfolge enthalten ist, oder wenn alle Segmente rechts vom Abschnitt Standardwerte von null aufweisen. Im Folgenden finden Sie gültige Vorlagenzeichenfolgen mit dem Standardwert null:

  • UriTemplate t = new UriTemplate("shoe/{boat=null}");

  • UriTemplate t = new UriTemplate("{shoe=null}/{boat=null}");

  • UriTemplate t = new UriTemplate("{shoe=1}/{boat=null}");

Im Folgenden finden Sie ungültige Vorlagenzeichenfolgen mit dem Standardwert null:

  • UriTemplate t = new UriTemplate("{shoe=null}/boat"); // null default must be in the right most path segment

  • UriTemplate t = new UriTemplate("{shoe=null}/{boat=x}/{bed=null}"); // shoe cannot have a null default because boat does not have a default null value

Standardwerte und Übereinstimmung

Beim Abgleichen eines Kandidaten-URI mit einer Vorlage mit Standardwerten werden die Standardwerte in der BoundVariables Auflistung platziert, wenn werte nicht im Kandidaten-URI angegeben sind.

Vorlagenäquivalenz

Zwei Vorlagen werden als strukturell gleichwertig bezeichnet, wenn alle Literale der Vorlagen übereinstimmen und Variablen in denselben Segmenten aufweisen. Die folgenden Vorlagen sind z. B. strukturell gleichwertig:

  • /a/{var1}/b/{var2}?x=1&y=2

  • a/{x}/b%20b/{var1}?y=2&x=1

  • a/{y}/B%20B/{z}/?y=2&x=1

Beachten Sie folgendes:

  • Wenn eine Vorlage führende Schrägstriche enthält, wird nur der erste ignoriert.

  • Wenn Vorlagenzeichenfolgen auf strukturelle Äquivalenz verglichen werden, wird die Groß-/Kleinschreibungen bei den Variablennamen und Pfadsegmenten ignoriert; bei den Abfragezeichenfolgen muss sie beachtet werden.

  • Abfragezeichenfolgen sind ungeordnet.

UriTemplateTable

Die UriTemplateTable Klasse stellt eine assoziative Tabelle von UriTemplate Objekten dar, die an ein Objekt der Auswahl des Entwicklers gebunden sind. Ein UriTemplateTable muss mindestens einen UriTemplate vor dem Aufrufen von MakeReadOnly(Boolean) enthalten. Der Inhalt einer UriTemplateTable kann bis zum Aufruf von MakeReadOnly(Boolean) geändert werden. Die Überprüfung wird ausgeführt, wenn MakeReadOnly(Boolean) aufgerufen wird. Der Typ der ausgeführten Validierung hängt vom Wert des allowMultiple Parameters zu MakeReadOnly(Boolean) ab.

Wenn MakeReadOnly(Boolean) bei Übergabe in false aufgerufen wird, überprüft die UriTemplateTable, dass sich keine Vorlagen in der Tabelle befinden. Wenn sie strukturell gleichwertige Vorlagen findet, löst sie eine Ausnahme aus. Dies wird in Verbindung mit MatchSingle(Uri) verwendet, wenn Sie sicherstellen möchten, dass nur eine Vorlage mit einem eingehenden URI übereinstimmt.

Wenn MakeReadOnly(Boolean) unter Verwendung von true aufgerufen wird, ermöglicht UriTemplateTable die Aufnahme mehrerer strukturell gleichwertiger Vorlagen in einem UriTemplateTable.

Wenn ein Satz UriTemplate-Objekte, die einer UriTemplateTable hinzugefügt sind, Abfragezeichenfolgen enthält, dürfen sie nicht mehrdeutig sein. Identische Abfragezeichenfolgen sind zulässig.

Hinweis

Während die UriTemplateTable Basisadressen, die andere Schemas als HTTP verwenden, zulassen, werden das Schema und die Portnummer beim Abgleichen von Kandidaten-URIs zu Vorlagen ignoriert.

Abfragezeichenfolgenmehrdeutigkeit

Vorlagen, die einen gleichwertigen Pfad gemeinsam verwenden, enthalten mehrdeutige Abfragezeichenfolgen, wenn ein URI vorhanden ist, der mehreren Vorlagen entspricht.

Die folgenden Sätze von Abfragezeichenfolgen sind in sich selbst eindeutig:

  • ?x=1

  • ?x=2

  • ?x=3

  • ?x=1&y={var}

  • ?x=2&z={var}

  • ?x=3

  • ?x=1

  • ?

  • ? x={var}

  • ?

  • ?m=get&c=rss

  • ?m=put&c=rss

  • ?m=get&c=atom

  • ?m=put&c=atom

Die folgenden Gruppen von Abfragezeichenfolgenvorlagen sind in sich selbst mehrdeutig:

  • ?x=1

  • ?x={var}

"x=1": Entspricht beiden Vorlagen.

  • ?x=1

  • ?y=2

"x=1&y=2" entspricht beiden Vorlagen. Dies liegt daran, dass eine Abfragezeichenfolge möglicherweise mehr Abfragezeichenfolgenvariablen enthalten kann als die Vorlage, zu der sie passt.

  • ?x=1

  • ?x=1&y={var}

"x=1&y=3" entspricht beiden Vorlagen.

  • ?x=3&y=4

  • ?x=3&z=5

Hinweis

Die Zeichen á und Á werden als unterschiedliche Zeichen betrachtet, wenn sie als Teil eines URI-Pfad- oder UriTemplate Pfadsegmentliterals angezeigt werden (die Zeichen a und A werden jedoch als identisch betrachtet). Die Zeichen á und Á werden als die gleichen Zeichen betrachtet, wenn sie als Teil einer UriTemplate {variableName} oder einer Abfragezeichenfolge angezeigt werden (und a und A werden auch als die gleichen Zeichen betrachtet).

Siehe auch