0

I need to connect to an API where the services URLs are case sensitive. For example, https://api-ABC.domain.com is different from https://api-abc.domain.com.

However, every time I create a new Uri object in C#, it converts the link to all lower case.

Here is my code:

var client = _httpClientFactory.CreateClient();

client.BaseAddress = new Uri($"https://api-{caseSensitiveAppId}.domain.com/v2/", UriKind.Absolute);

How can I create a Uri object that is case sensitive?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jay
  • 1,168
  • 13
  • 41
  • 1
    Generally accessing non-compliant resources (https://stackoverflow.com/questions/42375293/for-rest-apis-are-urls-meant-to-be-case-insensitive) is not supported... I'm pretty sure you need to drop to SSLStream level (or lower) and use your own name resolution outside regular DNS servers. – Alexei Levenkov Aug 25 '23 at 20:00
  • 1
    In C#, the Uri class normalizes the URI which generally includes converting the scheme and host to lowercase. This is done to comply with the RFC 3986 specification, which states that these components are case-insensitive. – jimmykurian Aug 25 '23 at 22:59

2 Answers2

0

To create a case sensitive Uri in C# you can use the UriBuilder class instead of the Uri class.

var builder = new UriBuilder();
builder.Scheme = "https";
builder.Host = $"api-{caseSensativeAppId}.domain.com"; 
builder.Path = "v2/";
sep7696
  • 494
  • 2
  • 16
0

Perhaps this solution would work for you:

  1. get the IP address from DNS by case sensitive host name
  2. use the received IP address in the URI instead of the original host name

Below is a very simple example to illustrate this idea

var hostName = "api-ABC.domain.com";
var uriStr = "https://{0}/v2/";
var ip = Dns.GetHostAddresses(hostName).First();
var uri = new Uri(string.Format(uriStr, ip), UriKind.Absolute);

var httpClient = new HttpClient();
var httpMsg = new HttpRequestMessage(HttpMethod.Get, uri);
httpMsg.Headers.Add("Host", hostName);
var response = await httpClient.SendAsync(httpMsg);
var content = await response.Content.ReadAsStringAsync();