Jaka jest różnica między Uri.ToString () a Uri.AbsoluteUri?


92

W komentarzu do pytania Azure, które właśnie się pojawiło, @smarx zauważył

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

Czy jest tego powód? W dokumentacji Uri.AbsoluteUrizauważono, że „Pobiera bezwzględny identyfikator URI”, Uri.ToString()„Pobiera kanoniczną reprezentację w postaci ciągu dla określonego wystąpienia”.


1
ToString sprawia, że ​​identyfikator URI jest bardziej czytelny, ale jednocześnie dekoduje wiele znaków zakodowanych w URLE, co w niektórych przypadkach będzie kłopotliwe. Zachowanie jest również różne w środowiskach wykonawczych platformy .net. Zobacz dhvik.blogspot.com/2019/12/ ... dla porównania.
Dan

Odpowiedzi:


103

Biorąc na przykład:

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

W takim przypadku Uri.ToString()zwróci czytelny dla człowieka adres URL: http: // jakiśhost / jakaś ścieżka? Somekey = jakaś + wartość

Uri.AbsoluteUri z drugiej strony zwróci zakodowany formularz, tak jak zwrócił go HttpUtility.UrlEncode: http://somehost/somepath?somekey=some%2bvalue


35
Ale pamiętaj, że „czytelny dla człowieka adres URL” (zwrócony z ToString) jest prawdopodobnie uszkodzony i prawie nigdy nie jest tym, czego chcesz: code.logos.com/blog/2010/08/uritostring_must_die.html . Unikałbym wywoływania ToString, gdy tylko to możliwe.
Bradley Grainger

1
Są chwile, w których chcesz ToString. Tutaj w SO jest świetny przykład (patrz moja odpowiedź powyżej). Chcesz „zwizualizować” adres URL. Chodzi o to (zawsze w programowaniu) - bądź ostrożny i wiedz, co robisz.
Ofer Zelig

3
Zwróć uwagę, że przykład tutaj (i w code.logos.com/blog/2010/08/uritostring_must_die.html ) nie jest już aktualny. Te problemy zostały rozwiązane w programie .NET Framework 4.5. Jednak metoda ToString () jest nadal przeznaczona tylko do reprezentacji adresu URL w postaci czytelnej dla człowieka (wizualnej). Jeśli skopiujesz ten adres URL do przeglądarki, powinien nadal działać.
arni

1
Wygląda na to, że najlepiej jest używać OriginialStringniż ToString()[ docs.microsoft.com/en-us/dotnet/api/ ...
karsnen

31

Dodatkowo: Jeśli urządzenie Urijest względna Uri AbsoluteUri nie powiedzie, ToString()nie.

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

5

Ponieważ wszyscy wydają się uważać, że uri.AbsoluteUrijest to lepsze, ale ponieważ nie udaje się to w przypadku ścieżek względnych, prawdopodobnie uniwersalny sposób byłby:

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

5

Dlaczego nie sprawdzić i użyć właściwego?

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

0

Poniższy przykład zapisuje pełną zawartość wystąpienia Uri w konsoli. W pokazanym przykładzie

http://www.cartechnewz.com/catalog/shownew.htm?date=today

jest zapisywane na konsoli.

Uri baseUri = new Uri("http://www.cartechnewz.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm?date=today");
Console.WriteLine(myUri.AbsoluteUri);

Właściwość AbsoluteUri obejmuje cały identyfikator URI przechowywany w wystąpieniu Uri, w tym wszystkie fragmenty i ciągi zapytań.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.