Substituir host em Uri

88

Qual é a melhor maneira de substituir a parte do host de um Uri usando o .NET?

Ie:

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 não parece ajudar muito.

Rasmus Faber
fonte

Respostas:

149

System.UriBuilder é o que você procura ...

string ReplaceHost(string original, string newHostName) {
    var builder = new UriBuilder(original);
    builder.Host = newHostName;
    return builder.Uri.ToString();
}
Ismael
fonte
1
Eu teria recomendado a aula de Uri, mas estaria errado. Boa resposta.
Jonathan C Dickinson
Funciona muito bem, apenas observe que se você ler a propriedade Query, ela é precedida por um?, E se você definir a propriedade Query com uma string começando com?, Outro? será prefixado.
Dave
Você terá que lidar com as portas, se elas forem especificadas no original ou no novo.
Realidade Subjetiva de
43

Como @Ishmael diz, você pode usar System.UriBuilder. Aqui está um exemplo:

// 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;
Drew Noakes
fonte
3
Suspeito que seja melhor obter a Uriinstância chamando em newUriBuilder.Urivez de formatá-la e analisá-la.
Sam
@Sam você está certo, o Uriimóvel é uma opção muito melhor. Obrigado. Atualizada.
Drew Noakes em
Cuidado com a .Uriligação. Se você tiver algo UriBuilderque não se traduza em um Uri válido, ele será lançado. Por exemplo, se você precisa de um host curinga, *pode defini .Host-lo, mas se você chamá- .Urilo, ele será lançado. Se você ligar, UriBuilder.ToString()ele retornará o Uri com o caractere curinga no lugar.
CubanX