Why does a slash make difference when using new URI(baseUri, relativePath)?
This constructor creates a Uri instance by combining the baseUri and the relativeUri ..
And, how can can a relative path be appended safely/consistently to a URI?
var badBase = new Uri("http://amee/noTrailingSlash");
var goodBase = new Uri("http://amee/trailingSlash/");
var f = "relPath";
new Uri(badBase, f) // BAD -> http://amee/relPath
new Uri(goodBase, f) // GOOD -> http://amee/trailingSlash/relPath
The desired output is "good" case, even when the initial URI does not have a trailing slash.
Why does a slash make difference when using new URI(baseUri, relativePath)?
Well, that's what happens on the web normally.
For example, suppose I'm looking at http://foo.com/some/file1.html
and there's a link to file2.html
- that link goes to http://foo.com/some/file2.html
, right? Not http://foo.com/some/file1.html/file2.html
.
More specifically though, this follows section 5.2.3 of RFC 3986.
5.2.3. Merge Paths
The pseudocode above refers to a "merge" routine for merging a relative-path reference with the path of the base URI. This is accomplished as follows:
If the base URI has a defined authority component and an empty path, then return a string consisting of "/" concatenated with the reference's path; otherwise,
return a string consisting of the reference's path component appended to all but the last segment of the base URI's path (i.e., excluding any characters after the right-most "/" in the base URI path, or excluding the entire base URI path if it does not contain any "/" characters).
I've been playing around with the Uri constructor with the overload new Uri(baseUri, relativePath)
. Perhaps others may find the results useful. Here's the output from the test application I wrote:
A) Base Address is domain only
==============================
NO trailing slash on base address, NO leading slash on relative path:
http://foo.com + relative1/relative2 :
http://foo.com/relative1/relative2
NO trailing slash on base address, relative path HAS leading slash:
http://foo.com + /relative1/relative2 :
http://foo.com/relative1/relative2
Base address HAS trailing slash, NO leading slash on relative path:
http://foo.com/ + relative1/relative2 :
http://foo.com/relative1/relative2
Base address HAS trailing slash, relative path HAS leading slash:
http://foo.com/ + /relative1/relative2 :
http://foo.com/relative1/relative2
B) Base Address includes path
=============================
NO trailing slash on base address, NO leading slash on relative path:
http://foo.com/base1/base2 + relative1/relative2 :
http://foo.com/base1/relative1/relative2
(removed base2 segment)
NO trailing slash on base address, relative path HAS leading slash:
http://foo.com/base1/base2 + /relative1/relative2 :
http://foo.com/relative1/relative2
(removed base1 and base2 segments)
Base address HAS trailing slash, NO leading slash on relative path:
http://foo.com/base1/base2/ + relative1/relative2 :
http://foo.com/base1/base2/relative1/relative2
(has all segments)
Base address HAS trailing slash, relative path HAS leading slash:
http://foo.com/base1/base2/ + /relative1/relative2 :
http://foo.com/relative1/relative2
(removed base1 and base2 segments)
I was looking for the same, and arrived at the following solution:
var badBase = new Uri("http://amee/noTrailingSlash");
var goodBase = new Uri("http://amee/trailingSlash/");
var f = "relPath";
string badBaseUrl = Path.Combine(badBase,f);
string goodBaseUrl = Path.Combine(goodBase,f);
new Uri(badBaseUrl); //----> (http://amee/trailingSlash/relPath)
new Uri(goodBaseUrl); //---> (http://amee/trailingSlash/relPath)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With