Почему HttpClient BaseAddress не работает?

рассмотрим следующий код, где BaseAddress определяет частичный путь 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");
}

Я ожидаю, что это выполнит GET запрос http://something.com/api/resource/7. Но это не так.--8-->

после некоторого поиска я нахожу этот вопрос и отвечаю: HttpClient с BaseAddress. Предложение-поставить / по конец 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");
}

он все еще не работает. Вот документация: С помощью HttpClient.Базовый адрес что что здесь происходит?

3 ответов


оказывается, что из четырех возможных перестановок включения или исключения трейлинг-или ведущих косых черт на BaseAddress и относительный URI перешел в GetAsync метод -- или любой другой метод HttpClient - только один перестановку работает. Вы должны поместите косую черту в конце BaseAddress и не должен поместите косую черту в начале вашего относительного 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");
}

хотя я ответил на свой вопрос, я решил, что внесу свой вклад в решение здесь, так как, опять же, это недружественное поведение недокументировано. Мой коллега и я потратили большую часть дня, пытаясь решить проблему, которая в конечном итоге была вызвана этой странностью HttpClient.


разрешение ссылки описывается RFC 3986 универсальный идентификатор ресурса (URI): универсальный синтаксис. И именно так это должно работать. Для сохранения базового пути URI необходимо добавить косую черту в конце базового URI и удалить косую черту в начале относительного URI.

если базовый URI содержит непустой путь, процедура слияния отбрасывает его последнюю часть (после last /). Уместно раздел:

5.2.3. Объединить Пути

псевдокод выше относится к процедуре "слияния" для слияния ссылка относительного пути с путем базового URI. Это выполнено следующим образом:

  • если базовый URI имеет определенный компонент полномочий и пустой path, затем возвращает строку, состоящую из"/", объединенную с путь ссылки; в противном случае

  • возвращает строку, состоящую из компонента пути ссылки добавлено ко всем, кроме последнего сегмента пути базового URI (т. е., исключая любые символы после "/" в базе Ури путь, или исключая весь базовый путь URI, если он не содержит никакие символы.)

если относительный URI начинается с косой черты, он называется относительным URI абсолютного пути. В этом случае процедура слияния игнорирует весь базовый путь URI. Для получения дополнительной информации посетите 5.2.2. Преобразование Ссылок раздел.


альтернативно-не используйте BaseAddress на всех. Поместите весь URL-адрес в GetAsync()