Dlaczego HttpClient BaseAddress nie działa?

Rozważ następujący kod, gdzie BaseAddress definiuje cząstkową ścieżkę URI.

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");
}

Oczekuję wykonania GET prośby do http://something.com/api/resource/7. Ale tak nie jest.

Po kilku poszukiwaniach znajduję to pytanie i odpowiadam: HttpClient z BaseAddress. Sugestia polega na umieszczeniu / na końcu BaseAddress.

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");
}
Nadal nie działa. Oto dokumentacja: HttpClient.BaseAddress co tu się dzieje?
Author: Community, 2014-05-03

3 answers

Okazuje się, że z czterech możliwych permutacji włączających lub wyłączających końcowe lub prowadzące do przodu ukośniki na BaseAddress i względny URI przekazany do metody GetAsync -- lub innej metody HttpClient -- tylko jedna permutacja działa. Musisz umieścić ukośnik na końcu BaseAddress, A nie możesz umieścić ukośnik na początku swojego względnego URI, jak w poniższym przykładzie.

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");
}
Mimo, że odpowiedziałem na własne pytanie, pomyślałem, że pomogę rozwiązać ten problem, ponieważ to nieprzyjazne zachowanie jest nieudokumentowane. Mój kolega i ja spędziliśmy większość dnia próbując naprawić problem, który ostatecznie został spowodowany przez tę dziwność HttpClient.
 407
Author: Timothy Shields,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 23:25:07

Rozdzielczość odniesienia jest opisana przez RFC 3986 Uniform Resource Identifier (URI): Generic Syntax. I dokładnie tak to powinno działać. Aby zachować ścieżkę Uri bazowego, należy dodać ukośnik na końcu Uri bazowego i usunąć ukośnik na początku Uri względnego.

Jeśli bazowy URI zawiera niepustą ścieżkę, procedura scalania odrzuca ostatnią część (po ostatniej /). Odpowiednia sekcja:

5.2.3. Merge Paths

The pseudokod powyżej odnosi się do procedury "merge" do scalania relative-odniesienie do ścieżki ze ścieżką bazowego URI. To jest wykonane w następujący sposób:

  • Jeśli bazowy URI ma zdefiniowany komponent authority i pusty path, następnie zwraca łańcuch składający się z " / " skonkatenowanego z ścieżka odniesienia; inaczej

  • Zwraca łańcuch składający się z komponentu ścieżki odniesienia dołączany do wszystkich oprócz ostatniego segmentu ścieżki Uri bazowego (tj., wykluczając znaki po prawej-najbardziej " / " w Uri bazowym ścieżka, lub wykluczenie całej podstawowej ścieżki URI, jeśli nie zawiera dowolne znaki"/").

Jeśli względny URI zaczyna się ukośnikiem, nazywa się go względnym Uri ścieżki bezwzględnej. W tym przypadku procedura merge ignoruje wszystkie podstawowe ścieżki URI. Aby uzyskać więcej informacji, sprawdź 5.2.2. Transform References section.

 19
Author: Leonid Vasilev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 16:14:19

Alternatywnie-nie używaj w ogóle BaseAddress. Wstaw cały adres URL GetAsync()

 2
Author: userSteve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 09:53:26