Consider the following code, where the BaseAddress
defines a partial URI path.
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");
}
I expect this to perform a GET
request to http://something.com/api/resource/7
. But it doesn't.
After some searching, I find this question and answer: HttpClient with BaseAddress. The suggestion is to place /
on the end of the 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");
}
It still doesn't work. Here's the documentation: HttpClient.BaseAddress What's going on here?
Alternatively - don't use
BaseAddress
at all. Put the whole URL inGetAsync
()It turns out that, out of the four possible permutations of including or excluding trailing or leading forward slashes on the
BaseAddress
and the relative URI passed to theGetAsync
method -- or whichever other method ofHttpClient
-- only one permutation works. You must place a slash at the end of theBaseAddress
, and you must not place a slash at the beginning of your relative URI, as in the following example.Even though I answered my own question, I figured I'd contribute the solution here since, again, this unfriendly behavior is undocumented. My colleague and I spent most of the day trying to fix a problem that was ultimately caused by this oddity of
HttpClient
.Ran into a issue with the HTTPClient, even with the suggestions still could not get it to authenticate. Turns out I needed a trailing '/' in my relative path.
i.e.
Reference Resolution is described by RFC 3986 Uniform Resource Identifier (URI): Generic Syntax. And that is exactly how it supposed to work. To preserve base URI path you need to add slash at the end of the base URI and remove slash at the beginning of relative URI.
If base URI contains non-empty path, merge procedure discards it's last part (after last
/
). Relevant section:If relative URI starts with a slash, it is called a absolute-path relative URI. In this case merge procedure ignore all base URI path. For more information check 5.2.2. Transform References section.