107

What is the nicest way of replacing the host-part of an Uri using .NET?

I.e.:

string ReplaceHost(string original, string newHostName); //... string s = ReplaceHost("http://oldhostname/index.html", "newhostname"); Assert.AreEqual("http://newhostname/index.html", s); //... string s = ReplaceHost("http://user:pass@oldhostname/index.html", "newhostname"); Assert.AreEqual("http://user:pass@newhostname/index.html", s); //... string s = ReplaceHost("ftp://user:pass@oldhostname", "newhostname"); Assert.AreEqual("ftp://user:pass@newhostname", s); //etc. 

System.Uri does not seem to help much.

3 Answers 3

183

System.UriBuilder is what you are after...

string ReplaceHost(string original, string newHostName) { var builder = new UriBuilder(original); builder.Host = newHostName; return builder.Uri.ToString(); } 
Sign up to request clarification or add additional context in comments.

3 Comments

I would have recommended the Uri class, but I would have been wrong. Good answer.
Works great, just note that if you read the Query property, it is prepended with a ?, and if you set the Query Property with a string beginning with ?, another ? will be prepended.
You'll have to handle ports, if they are specified in either original or new.
45

As @Ishmael says, you can use System.UriBuilder. Here's an example:

// the URI for which you want to change the host name var oldUri = Request.Url; // create a new UriBuilder, which copies all fragments of the source URI var newUriBuilder = new UriBuilder(oldUri); // set the new host (you can set other properties too) newUriBuilder.Host = "newhost.com"; // get a Uri instance from the UriBuilder var newUri = newUriBuilder.Uri; 

3 Comments

I suspect it might be better to obtain the Uri instance by calling newUriBuilder.Uri rather than formatting and parsing it.
@Sam you're right, the Uri property is a much better option. Thanks. Updated.
Careful of the .Uri call. If you have something in that UriBuilder that does not translate to a valid Uri, it will throw. So for example if you need a wildcard host * you can set .Host to that, but if you call .Uri it will throw. If you call UriBuilder.ToString() it will return the Uri with the wildcard in place.
0

The answer using UriBuilder is fine, except it may trigger an exception if the host to be replaced is in the form "machinename:port".

This is the refined code i have used to handle also this common situation:

public static Uri ReplaceHost(Uri original, string newHostName) { var builder = new UriBuilder(original); var newhost = new Uri(newHostName.Contains("://") ? newHostName : "http://" + newHostName); builder.Host = newhost.Host; builder.Port = newhost.Port == 80 ? builder.Port : newhost.Port; return builder.Uri; } 

Note that if you do not specify a new port, the old port is retained

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.