16

I recently became aware of the odd behavior of Uri.ToString() (namely, it unencodes some characters and therefore is primarily suitable for display purposes). I'm trying to decide between AbsoluteUri and OriginalString as my "go-to" for converting a Uri object to a string (e. g. in a razor view).

So far, the only difference I've found between the two is that AbsoluteUri will fail for relative uris (e. g. new Uri("foo", UriKind.Relative).AbsoluteUri). That seems like a point in favor of OriginalString. However, I'm concerned by the word "original", since it suggests that maybe some things will not get properly encoded or escaped.

Can anyone confirm the difference between these two properties (aside from the one difference I found)?

ChaseMedallion
  • 20,860
  • 17
  • 88
  • 152

3 Answers3

12

I always favor OriginalString as I've ran into multiple issues with AbsoluteUri. Namely:

AbsoluteUri behaves differently in .NET 4.0 vs .NET 4.5 (see)

.NET Framework 4.0

var uri = new Uri("http://www.example.com/test%2F1");

Console.WriteLine(uri.OriginalString);
// http://www.example.com/test%2F1

Console.WriteLine(uri.AbsoluteUri);
// http://www.example.com/test/1  <--  WRONG

.NET Framework 4.5

var uri = new Uri("http://www.example.com/test%2F1");

Console.WriteLine(uri.OriginalString);
// http://www.example.com/test%2F1

Console.WriteLine(uri.AbsoluteUri);
// http://www.example.com/test%2F1

AbsoluteUri doesn't support relative URIs

var uri = new Uri("/test.aspx?v=hello world", UriKind.Relative);

Console.WriteLine(uri.OriginalString);
// /test.aspx?v=hello world

Console.WriteLine(uri.AbsoluteUri);
// InvalidOperationException: This operation is not supported for a relative URI.

AbsoluteUri does unwanted escaping

var uri = new Uri("http://www.example.com/test.aspx?v=hello world");

Console.WriteLine(uri.OriginalString);
// http://www.example.com/test.aspx?v=hello world

Console.WriteLine(uri.AbsoluteUri);
// http://www.example.com/test.aspx?v=hello%20world  <--  WRONG
Daniel Liuzzi
  • 16,807
  • 8
  • 52
  • 57
  • 5
    Regarding the last point, `http://www.example.com/test.aspx?v=hello%20world` is a valid URL, as spaces must be escape. OriginalString gives invalid URL suitable for viewing only – Jeow Li Huan Nov 08 '17 at 05:04
  • 1
    I didn't say it's invalid; I said it's _wrong_, at least in the context of this question. I intentionally used and invalid URL to highlight the difference; the author talks about Uri.ToString() decoding some characters. AbsoluteUri suffers from this also, except it _encodes_ some characters. If you want the original, __unaltered__ URL (as in… the one used to instantiate the Uri object at hand, no encoding, no decoding), `OriginalString` provides just that. If this URL is invalid, I'd much rather find out how it got there in the first place and not have AbsoluteUri cover it up. – Daniel Liuzzi Nov 08 '17 at 10:03
  • "http://www.example.com/test%2F1" doesnn't look like a valid url, expect query params to be encoded only. Correct me if I am wrong – Artiom May 21 '19 at 08:23
  • `example.com/test%2F1` does not contain any invalid characters so it _is_ a valid URL. Although the query string is the most common usage, URL encoding is not limited to it. According to [MDN](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding), _percent-encoding is a mechanism to encode 8-bit characters that have specific meaning **in the context of URLs**_. – Daniel Liuzzi May 21 '19 at 12:53
9

Normalization is a good reason to use AbsoluteUri over OriginalString:

new Uri("http://foo.bar/var/../gar").AbsoluteUri // http://foo.bar/gar
new Uri("http://foo.bar/var/../gar").OriginalString // http://foo.bar/var/../gar
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Is the normalization part of API definition? – Xolve Feb 09 '22 at 18:50
  • 1
    @Xolve are you asking about whether Uri is documented to return normalized (canonical) value (https://learn.microsoft.com/en-us/dotnet/api/system.uri?view=net-6.0#remarks) or what [Uri normalization](https://en.wikipedia.org/wiki/URI_normalization) is? – Alexei Levenkov Feb 09 '22 at 19:27
0

For converting a Uri object to a string I was using

Location.ToString().StripQuotes();

Note that ToString generated url string wrapped with double quotes ", and I had to remove them using StripQuotes from Flurl/src/Flurl/Util/CommonExtensions.cs

See also MSDN example that illustrates the difference between the value returned from OriginalString, which returns the string that was passed to the constructor, and from a call to ToString, which returns the canonical form of the string.

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170