Заменить хост в Uri

86

Как лучше всего заменить хост-часть URI с помощью .NET?

Т.е.:

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, похоже, не сильно помогает.

Расмус Фабер
источник

Ответы:

148

System.UriBuilder - это то, что вам нужно ...

string ReplaceHost(string original, string newHostName) {
    var builder = new UriBuilder(original);
    builder.Host = newHostName;
    return builder.Uri.ToString();
}
Измаил
источник
Спасибо, это именно то, что я искал.
Расмус Фабер,
1
Я бы порекомендовал класс Uri, но ошибался. Хороший ответ.
Джонатан Дикинсон,
Отлично работает, просто обратите внимание, что если вы читаете свойство Query, перед ним ставится?, А если вы устанавливаете свойство Query со строкой, начинающейся с?, Другой? будет добавлено.
Дэйв
Вам придется обрабатывать порты, если они указаны в исходном или новом.
Субъективная реальность
42

Как говорит @Ishmael, вы можете использовать System.UriBuilder. Вот пример:

// 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
Я подозреваю, что было бы лучше получить Uriэкземпляр путем вызова, newUriBuilder.Uriа не форматирования и анализа.
Сэм
@ Сэм, ты прав, Uriнедвижимость намного лучше. Спасибо. Обновлено.
Дрю Ноукс
Осторожно относитесь к .Uriзвонку. Если у вас есть что-то, UriBuilderчто не переводится в действительный Uri, оно будет брошено. Так, например, если вам нужен хост с подстановочными знаками, *вы можете установить .Hostего, но если вы вызовете, .Uriон выдаст. Если вы вызовете, UriBuilder.ToString()он вернет Uri с подстановочным знаком.
CubanX