'HttpClient Modifies BaseAddress in Some Cases [duplicate]
On a basic level, I should be able to set an absolute BaseAddress
on HttpClient
and then send Http requests with a relative Uri
. The expectation is that the relative Uri
would append on to the base address to make the Http call. It does this in most cases. This example works fine.
Edit: see the bottom. This appears to be weird behavior in the way Uris are constructed.
var httpClient = new HttpClient() { BaseAddress = new Uri("http://restcountries.eu/rest/", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("v2", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Fiddler url:
GET http://restcountries.eu/rest/v2 HTTP/1.1
I have a local API. When I run the equivalent on my local API, the call truncates part of the base address ("Api").
var httpClient = new HttpClient() { BaseAddress = new Uri($"http://localhost/JsonPerson/Api", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("GetApiPerson", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Fiddler url:
GET http://localhost/JsonPerson/GetApiPerson HTTP/1.1
Why does is it remove "/Api" ?
This code hits the local API and works fine:
var httpClient = new HttpClient() { BaseAddress = new Uri($"http://localhost/JsonPerson/", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("Api/GetApiPerson", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Fiddler url:
GET http://localhost/JsonPerson/Api/GetApiPerson HTTP/1.1
This is a bizarre problem and I can't figure out why I get these inconsistencies... Is it treating the uri differently for local and non local uris? What am I missing here?
This is .NET Core 3.1
Look at this code, and then have a look at the output. This is what HttpClient
is doing behind the scenes.
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
var baseAddress = new Uri($"http://restcountries.eu/JsonPerson/Api", UriKind.Absolute);
var resourceUri = new Uri($"GetApiPerson", UriKind.Relative);
Console.WriteLine(new Uri(baseAddress, resourceUri));
baseAddress = new Uri($"http://restcountries.eu/JsonPerson", UriKind.Absolute);
resourceUri = new Uri($"Api/GetApiPerson", UriKind.Relative);
Console.WriteLine(new Uri(baseAddress, resourceUri));
baseAddress = new Uri($"http://restcountries.eu/rest/", UriKind.Absolute);
resourceUri = new Uri($"v2", UriKind.Relative);
Console.WriteLine(new Uri(baseAddress, resourceUri));
}
}
}
Output
It turns out that this thing seems to have something to do with it...
Solution 1:[1]
Putting a slash on the end of the BaseAddress
resolves the issue.
However, this kind of seems like a bug in Uri
to me. I'm sure this trips up tonnes of people.
I created a library called Urls which addresses this issue. Urls are immutable and you don't have to construct them with strings.
RestClient.Net is a REST/HTTP client library that uses these urls. You can read more about the issue here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |