BCS
BCS

Reputation: 78683

How to combine URIs

I have two Uri objects passed into some code, one is a directory and the other is a filename (or a relative path)

var a = new Uri("file:///C:/Some/Dirs");
var b = new Uri("some.file");

when I try and combine them like this:

var c = new Uri(a,b);

I get

file:///C:/Some/some.file

where I wold expect to get the same effect as with Path.Combine (as that is the old code I need to replace):

file:///C:/Some/Dirs/some.file

I can't think of a clean solution to this.

The ugly solution being to add a / to the Uri if it's not there

string s = a.OriginalString;
if(s[s.Length-1] != '/')
   a = new Uri(s + "/");

Upvotes: 22

Views: 23393

Answers (5)

brianbruff
brianbruff

Reputation: 291

This should do the trick for you:

var baseUri = new Uri("http://www.briankeating.net");
var absoluteUri = new Uri(baseUri, "/api/GetDefinitions");

This constructor follow the standard relative URI rules so the / are important :

  • http://example.net + foo = http://example.net/foo
  • http://example.net/foo/bar + baz = http://example.net/foo/baz
  • http://example.net/foo/ + bar = http://example.net/foo/bar
  • http://example.net/foo + bar = http://example.net/bar
  • http://example.net/foo/bar/ + /baz = http://example.net/baz

Upvotes: 26

Angelo Nodari
Angelo Nodari

Reputation: 385

You can try this extension method! Works always! ;-)

 public static class StringExtension
    {
        public static string UriCombine(this string str, string param)
        {
            if (!str.EndsWith("/"))
            {
                str = str + "/";
            }
            var uri = new Uri(str);
            return new Uri(uri, param).AbsoluteUri;
        }
    }

Angelo, Alessandro

Upvotes: 6

Tolgahan Albayrak
Tolgahan Albayrak

Reputation: 3206

add a slash end of your first uri, URI will ignore more than one slash (/)

var a = new Uri("file:///C:/Some/Dirs/");

EDIT:

var a = new Uri("file:///C:/Some/Dirs");
var b = new Uri("some.file",  UriKind.Relative);
var c = new Uri(Path.Combine(a.ToString(), b.ToString()));
MessageBox.Show(c.AbsoluteUri);

Upvotes: 2

rama-jka toti
rama-jka toti

Reputation: 1436

Why not just inherit from Uri and use that, ie. do in constructor what you need to do to fix it up? Refactoring is cheap assuming this is internal to assembly or within reach..

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1504022

Well, you're going to have to tell the Uri somehow that the last part is a directory rather than a file. Using a trailing slash seems to be the most obvious way to me.

Bear in mind that for many Uris, the answer you've got is exactly right. For example, if your web browser is rendering

http://foo.com/bar/index.html

and it sees a relatively link of "other.html" it then goes to

http://foo.com/bar/other.html

not

http://foo.com/bar/index.html/other.html

Using a trailing slash on "directory" Uris is a pretty familiar way of suggesting that relative Uris should just append instead of replacing.

Upvotes: 17

Related Questions