Constructing uris in dotnet is harder than it should

jonassamuelsson

Jonas Samuelsson

Posted on October 16, 2020

Constructing uris in dotnet is harder than it should

A common pattern for communicating over http in dotnet is to use a HttpClient with a base address and then add a relative path for every request. If the base address includes a parts of the path, one has to be very careful of where slashes are added or the resulting uri wont be what you expect.

We recently got bit by this at work where we suddenly started getting 404s on all requests going from one service to another.
As it turned out we had made a configuration change and a missing trailing slash in the base address was the reason.

This little sample demonstrates what happened

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  public static void Main()
  {
    var baseAddresses = new [] { "http://host.io/foo", "http://host.io/foo/" };
    var relativeAddresses = new [] { "bar", "/bar" };

    foreach (var baseAddress in baseAddresses)
    {
      foreach (var relativeAddress in relativeAddresses)
      {
        var uri = new Uri(new Uri(baseAddress), relativeAddress).AbsoluteUri;
        Console.WriteLine($"{baseAddress} + {relativeAddress} = {uri}");
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

And the output is

http://host.io/foo + bar = http://host.io/bar
http://host.io/foo + /bar = http://host.io/bar
http://host.io/foo/ + bar = http://host.io/foo/bar
http://host.io/foo/ + /bar = http://host.io/bar
Enter fullscreen mode Exit fullscreen mode

As you can see, in three out of four possible combinations the foo part of the base address is silently removed from the final uri. 😱

💖 💪 🙅 🚩
jonassamuelsson
Jonas Samuelsson

Posted on October 16, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related