2011-10-02 10 views
62

jako komentarz do Azure pytanie właśnie teraz, @smarx zauważyćJaka jest różnica między Uri.ToString() a Uri.AbsoluteUri?

Myślę, że to generalnie lepiej zrobić blob.Uri.AbsoluteUri niż blob.Uri.ToString().

Czy istnieje ku temu powód? Dokumentacja dla Uri.AbsoluteUri stwierdza, że ​​"Pobiera bezwzględny identyfikator URI", Uri.ToString() "Pobiera kanoniczną reprezentację ciągów dla określonej instancji."

Odpowiedz

74

Zważywszy na przykład:

UriBuilder builder = new UriBuilder("http://somehost/somepath"); 
builder.Query = "somekey=" + HttpUtility.UrlEncode("some+value"); 
Uri someUri = builder.Uri; 

W tym przypadku Uri.ToString() powróci do postaci czytelnej dla człowieka URL: http://somehost/somepath?somekey=some+value

Uri.AbsoluteUri natomiast powróci formę zakodowaną jako HttpUtility.UrlEncode powrócił go : http://somehost/somepath?somekey=some%2bvalue

+24

Należy jednak pamiętać, że „URL czytelny dla człowieka” (wrócił z ToString) jest prawdopodobnie uszkodzony i prawie nigdy, co chcesz: http://code.logos.com/blog/2010/08/uritostring_must_die.html . Unikałbym dzwonienia do ToStringa, gdy tylko było to możliwe. –

+1

Są chwile, w których chcesz wykonać ToString. Tutaj w SO jest świetnym przykładem (zobacz moją odpowiedź powyżej). Chcesz "zwizualizować" adres URL. Punkt (zawsze w programowaniu) jest - bądź ostrożny i wiedz, co robisz. –

+2

Należy zauważyć, że przykład tutaj (oraz w http://code.logos.com/blog/2010/08/uritostring_must_die.html) nie są już aktualne. Te problemy zostały naprawione w programie .NET Framework 4.5. Jednak funkcja ToString() jest w dalszym ciągu przeznaczona tylko do czytelnej (wizualnej) reprezentacji adresu URL. Jeśli skopiujesz ten adres URL do przeglądarki, powinien on nadal działać. – arni

22

Dodatkowo: Jeśli twoja Uri jest względnaUriAbsoluteUri zawiedzie, ToString() nie.

Uri uri = new Uri("fuu/bar.xyz", UriKind.Relative); 
string str1 = uri.ToString(); // "fuu/bar.xyz" 
string str2 = uri.AbsoluteUri; // InvalidOperationException 
3

Ponieważ każdy zdaje się myśleć, że uri.AbsoluteUri jest lepsze, ale ponieważ nie jest on z względnymi ścieżkami, to prawdopodobnie uniwersalny sposób byłoby:

Uri uri = new Uri("fuu/bar.xyz", UriKind.Relative); 
string notCorruptUri = Uri.EscapeUriString(uri.ToString()); 
2

Dlaczego nie sprawdzić i używać poprawny?

string GetUrl(Uri uri) => uri?.IsAbsoluteUri == true ? uri?.AbsoluteUri : uri?.ToString(); 
Powiązane problemy