Junior Mayhe
Junior Mayhe

Reputation: 16411

Why does the URI constructor remove part of path from the baseUri argument?

public class Program
{
    public static void Main()
    {
        Uri baseUri = new Uri("http://localhost:7777/BasePath/");
        Uri uri = new Uri(baseUri, "/controller");
        Console.WriteLine(uri);
    }
}

Is it the intend behavior to wipe /BasePath out from uri and the final result be http://localhost:7777/controller?

Upvotes: 6

Views: 1921

Answers (2)

Dmitry Melnikov
Dmitry Melnikov

Reputation: 96

I wrote a simple unit test for Uri(baseUri, relativeUri) constructor .NET 7.0 and found out that the relative part of the baseUri is preserved only in one case, when:

  • baseUri ends with slash '/'
  • relativeUri to be added does not start with '/'

all cases below are successful

    [Theory]
    [InlineData("http://my.host.net",      "some/path",  "http://my.host.net/some/path")]
    [InlineData("http://my.host.net/net",  "/some/path", "http://my.host.net/some/path")]
    [InlineData("http://my.host.net/net",  "some/path",  "http://my.host.net/some/path")]
    [InlineData("http://my.host.net/net",  "some/path/", "http://my.host.net/some/path/")]
    [InlineData("http://my.host.net/net/", "/some/path", "http://my.host.net/some/path")]
    [InlineData("http://my.host.net/net/", "some/path",  "http://my.host.net/net/some/path")]
    [InlineData("http://my.host.net/net/", "some/path/", "http://my.host.net/net/some/path/")]
    public void CreateUriTest(string baseUrl, string path, string full)
    {
        var baseUri = new Uri(baseUrl);
        var fullUri = new Uri(baseUri, path);
        Assert.Equal(full, fullUri.ToString());
    }

MSDN for .NET 7.0 explanation for Uri(Uri, String) constructor is a bit unclear. It has 2 contradictory statements:

If the baseUri has relative parts (like /api), then the relative part must be terminated with a slash, (like /api/), if the relative part of baseUri is to be preserved in the constructed Uri.

Additionally, if the relativeUri begins with a slash, then it will replace any relative part of the baseUri

The second statement always wins. In other words, starting '/' of the relativeUri does replace the relative part of the baseUri regardless of if it ends with a '/' or not.

Upvotes: 2

Scott Hannen
Scott Hannen

Reputation: 29202

I had to dig into the documentation for the constructor you're calling.

public Uri (Uri baseUri, string relativeUri);

Additionally, if the relativeUri begins with a slash, then it will replace any relative part of the baseUri.

It's the intended behavior. If you specify a relative path that begins with a slash, it assumes that the relative path is the entire relative path, so it discards any relative path already included in baseUri.

Upvotes: 8

Related Questions