2014-05-02 6 views
134

Betrachten Sie den folgenden Code, wobei BaseAddress einen partiellen URI-Pfad definiert.Warum funktioniert HttpClient BaseAddress nicht?

using (var handler = new HttpClientHandler()) 
using (var client = new HttpClient(handler)) 
{ 
    client.BaseAddress = new Uri("http://something.com/api"); 
    var response = await client.GetAsync("/resource/7"); 
} 

Ich erwarte, dass dies eine GET Anfrage http://something.com/api/resource/7 auszuführen. Aber das tut es nicht.

Nach einigem Suchen finde ich diese Frage und Antwort: HttpClient with BaseAddress. Der Vorschlag ist, / am Ende der BaseAddress zu platzieren.

using (var handler = new HttpClientHandler()) 
using (var client = new HttpClient(handler)) 
{ 
    client.BaseAddress = new Uri("http://something.com/api/"); 
    var response = await client.GetAsync("/resource/7"); 
} 

Es funktioniert immer noch nicht. Hier ist die Dokumentation: HttpClient.BaseAddress Was ist hier los?

+0

Mögliches Duplikat von [HttpClient mit BaseAddress] (http://stackoverflow.com/questions/20609118/httpclient-with-baseaddress) –

+0

@ ГеоргийЛанец Das umgekehrte Duplikat wurde bereits vorgeschlagen. Ich habe diese Frage speziell geschrieben, weil diese andere Frage nicht auf eine Weise geschrieben wurde, die für Leute mit dem gleichen Problem sehr auffindbar war, und ich schrieb die Antwort hier, weil die Antwort dort einen wichtigen Punkt verließ. –

+0

aber diese Frage wird später gestellt –

Antwort

318

Es stellt sich heraus, dass von den vier möglichen Permutationen mit oder ohne stechend oder schleppend vorwärts Schrägstriche auf dem BaseAddress und die relative URI zum GetAsync Methode übergeben - oder Unabhängig davon, welche andere Methode der HttpClient - nur ein Permutation funktioniert. Sie müssen platzieren Sie einen Schrägstrich am Ende der BaseAddress, und Sie müssen nicht platzieren Sie einen Schrägstrich am Anfang Ihrer relativen URI, wie im folgenden Beispiel.

using (var handler = new HttpClientHandler()) 
using (var client = new HttpClient(handler)) 
{ 
    client.BaseAddress = new Uri("http://something.com/api/"); 
    var response = await client.GetAsync("resource/7"); 
} 

Auch wenn ich meine eigene Frage beantworten, dachte ich, ich die Lösung hier beitragen würde, da wieder, dieses unfreundliche Verhalten nicht dokumentiert ist. Mein Kollege und ich verbrachten den größten Teil des Tages damit, ein Problem zu lösen, das letztendlich durch diese Kuriosität von HttpClient verursacht wurde.

+0

Es hängt nur davon ab, wo Sie anfangen. Wenn Sie mit Microsoft-Artikeln wie http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client beginnen, werden Sie das tun vermeide den falschen Code. –

+0

Klingt, als hätte jemand von Microsoft den Link http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.baseaddress(v=vs.118).aspx aktualisiert, was ich nochmal gelesen habe Ich tippte und ich wollte nicht "unhöflich" sein, da ich nur mehr Fakten darüber lieferte, wie Microsoft versucht, eine API zu dokumentieren. Die Offenheit von SO ist, dass es Kommentare ermöglicht und jeder seine Meinung teilen kann. Sie haben Ihre Antwort geliefert, damit zukünftige Leser Zeit sparen können, und ich habe mit Absicht kommentiert, um ihnen in ähnlichen Fällen mehr Zeit zu sparen. Grüße, –

+0

Der abschließende Schrägstrich auf einer Basisadresse fängt uns alle irgendwann. http://www.bizcoder.com/2009/02/24/the-mystery-of-the-trailing-slash-and-the-relative-url/ –

3

Referenz Auflösung wird von RFC 3986 Uniform Resource Identifier (URI): Generic Syntax beschrieben. Und genau so sollte es funktionieren. Um den Basis-URI-Pfad beizubehalten, müssen Sie am Ende des Basis-URI einen Schrägstrich hinzufügen und am Anfang des relativen URI den Schrägstrich entfernen.

Wenn der Basis-URI einen nicht leeren Pfad enthält, verwirft der Mischvorgang den letzten Teil (nach dem letzten /). Relevant section:

5.2.3. Merge-Pfade

Der Pseudocode oben bezieht sich auf eine "Merge" -Routine zum Zusammenführen eines relativen Pfadverweises mit dem Pfad des Basis-URI. Dies wird wie folgt erreicht :

  • Wenn die Basis-URI hat eine definierte Stelle Komponente und einen leeren Pfad, dann eine Zeichenkette zurück, die aus „/“ verketteten mit dem Pfad Verweises des; sonst

  • return einen String der Pfadkomponente des Referenz bestehend für alle bis auf das letzte Segment des Basis Pfad URI anhängenden (dh ohne irgendwelche Zeichen nach dem am weitesten rechts stehenden „/“ in der Basis URI Pfad, oder den gesamten Basis-URI-Pfad auszuschließen, wenn er keine "/" - Zeichen enthält.

Wenn relative URI beginnt mit einem Schrägstrich, wird es einen absoluten Pfad relative URI genannt. In diesem Fall ignoriert die Merge-Prozedur alle Basis-URI-Pfade. Weitere Informationen finden Sie im Abschnitt 5.2.2. Transform References.

Verwandte Themen