Bug 39390 - System.Uri constructor with baseUri behaves differently than .net framework Uri
Summary: System.Uri constructor with baseUri behaves differently than .net framework Uri
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: 4.2.0 (C6)
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Marek Safar
Depends on:
Reported: 2016-03-05 18:58 UTC by Nathan Phillip Brink (binki)
Modified: 2016-05-11 12:00 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

DemoProgram.cs (890 bytes, text/plain)
2016-03-05 18:58 UTC, Nathan Phillip Brink (binki)
Testcase for Uri overload issue. (461 bytes, text/plain)
2016-03-08 22:46 UTC, virtlink

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Nathan Phillip Brink (binki) 2016-03-05 18:58:29 UTC
Created attachment 15277 [details]

When using the Uri(Uri, string) constructor, Mono seems to treat the string as if it is relative when it shouldn’t. For example, if the base URI is “asdf:a/b” and the URI being resolved against that base is “asdf:c”, mono behaves as if the URI being resolved against the base is “c”.

The documentation about Uri(Uri, string) at https://msdn.microsoft.com/en-us/library/9hst1w91%28v=vs.110%29.aspx states “If relativeUri is an absolute URI (containing a scheme, host name, and optionally a port number), the Uri instance is created using only relativeUri.”. The documentation seems to suggest that a host must be specified to make the URI absolute, but all that is needed to make .net consider the relativeUri absolute is the presence of a scheme. Yet mono treats the scheme as if its presence does *not* cause mono to consider the passed in relativeUri to be absolute.

Also, mono will interpret “asdf:” as “asdf:” when using the normal Uri(string) constructor. However, when “asdf:” is resolved when provided the baseUri of “asdf:”, mono comes up with a “/” (“asdf:/”) out of nowhere. This seems to be another failure of it to ignore the provided provided baseUri when the relativeUri is absolute.

It’d be nice to write code against Uri without having to worry about it behaving differently if I were to run it under mono.

C:\Users\ohnob\OneDrive\Documents\Visual Studio 2015\Projects\MonoUri\MonoUri\bin\Debug>mono --version
Mono JIT compiler version 4.2.2 (Visual Studio built mono)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           normal
        SIGSEGV:       normal
        Notification:  Thread + polling
        Architecture:  x86
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

C:\Users\ohnob\OneDrive\Documents\Visual Studio 2015\Projects\MonoUri\MonoUri\bin\Debug>cat ..\..\Program.cs
using System;
class Program
    static void l(object o = null) => Console.WriteLine(o);
    static int Main(string[] args)
        // Not sure where the “/” is coming from.
        l(new Uri(new Uri("asdf:"), "asdf:")); // .net “asdf:”, mono “asdf:/”
        // When relativeUri is absolute, new Uri(baseUri, relativeUri) should be
        // equivalent to calling new Uri(relativeUri). In .net it is, in mono not so much:
        l(new Uri("asdf:")); // .net “asdf:”, mono “asdf:”.

        l(new Uri(new Uri("asdf:/a/b/"), "asdf:c")); // .net “asdf:c”, mono “asdf:/a/b/c”
        l(new Uri(new Uri("asdf:/a/b/"), "c")); // .net “asdf:/a/b/c”, mono “asdf:/a/b/c”—they agree
        l(new Uri(new Uri("blah:/a/b/"), "asdf:c")); // .net “asdf:c”, mono “asdf:c”—they agree

        return 0;

C:\Users\ohnob\OneDrive\Documents\Visual Studio 2015\Projects\MonoUri\MonoUri\bin\Debug>mono .\MonoUri.exe


C:\Users\ohnob\OneDrive\Documents\Visual Studio 2015\Projects\MonoUri\MonoUri\bin\Debug>.\MonoUri.exe


C:\Users\ohnob\OneDrive\Documents\Visual Studio 2015\Projects\MonoUri\MonoUri\bin\Debug>
Comment 1 virtlink 2016-03-08 22:46:00 UTC
Created attachment 15319 [details]
Testcase for Uri overload issue.

I have the same problem with the new Uri(Uri, string) overload. In this code:

    var result = new Uri(new Uri("zip:mem:///"), "zip:mem:///foo/bar.txt");

I expect the result to be:


But instead I get:


On Mono Stable in Linux.
Comment 2 Marek Safar 2016-05-11 12:00:40 UTC
Fixed in master