[System] UriKind.RelativeOrAbsolute workaround.
authorMarcos Henrich <marcos.henrich@xamarin.com>
Thu, 23 Jul 2015 17:56:33 +0000 (18:56 +0100)
committerMarcos Henrich <marcos.henrich@xamarin.com>
Fri, 24 Jul 2015 08:58:41 +0000 (09:58 +0100)
In .NET an URI constructor from "/foo" and UriKind.RelativeOrAbsolute is
relative whereas in mono it is assumed as an absolute file path.

This provides supports for an easy workaround to make mono behave as
.NET.

The workaround consists in defining DotNetRelativeOrAbsolute and using
it instead of UriKind.RelativeOrAbsolute.

DotNetRelativeOrAbsolute should be defined as follows:

static UriKind DotNetRelativeOrAbsolute = (Type.GetType ("Mono.Runtime")
== null)? UriKind.RelativeOrAbsolute : (UriKind) 300;

mcs/class/System/System/Uri.cs
mcs/class/System/Test/System/UriTest.cs

index a1417e99527c0bd59f0befff9246110310ab4080..be05c6dfc7d2df849b9c9aed91b93e47597a31c7 100644 (file)
@@ -170,9 +170,16 @@ namespace System {
                        }
                }
 
+               // When used instead of UriKind.RelativeOrAbsolute paths such as "/foo" are assumed relative.
+               const UriKind DotNetRelativeOrAbsolute = (UriKind) 300;
+
                public Uri (string uriString, UriKind uriKind)
                {
                        source = uriString;
+
+                       if (uriString != null && uriKind == DotNetRelativeOrAbsolute)
+                               uriKind = (uriString.StartsWith ("/", StringComparison.Ordinal))? UriKind.Relative : UriKind.RelativeOrAbsolute;
+
                        ParseUri (uriKind);
 
                        switch (uriKind) {
@@ -205,6 +212,9 @@ namespace System {
                                return;
                        }
 
+                       if (uriKind == DotNetRelativeOrAbsolute)
+                               uriKind = (uriString.StartsWith ("/", StringComparison.Ordinal))? UriKind.Relative : UriKind.RelativeOrAbsolute;
+
                        if (uriKind != UriKind.RelativeOrAbsolute &&
                                uriKind != UriKind.Absolute &&
                                uriKind != UriKind.Relative) {
index e9a92244f63c27b1eb745d3c792d8fdb6cbae586..33484e5326d6ef031b9c9847ffcc11d7e073f185 100644 (file)
@@ -1940,6 +1940,20 @@ namespace MonoTests.System
                        Assert.AreEqual ("id=1%262&sort=asc", escaped, "UriEscaped");
                }
 
+               // When used, paths such as "/foo" are assumed relative.
+               static UriKind DotNetRelativeOrAbsolute = (Type.GetType ("Mono.Runtime") == null)? UriKind.RelativeOrAbsolute : (UriKind) 300;
+
+               [Test]
+               public void DotNetRelativeOrAbsoluteTest ()
+               {
+                       var uri1 = new Uri ("/foo", DotNetRelativeOrAbsolute);
+                       Assert.IsFalse (uri1.IsAbsoluteUri);
+                       
+                       Uri uri2;
+                       Uri.TryCreate("/foo", DotNetRelativeOrAbsolute, out uri2);
+                       Assert.IsFalse (uri2.IsAbsoluteUri);
+               }
+
                [Test]
                // Bug #12631
                public void LocalPathWithBaseUrl ()