【问题标题】:Uri.AbsoluteUri vs. Uri.OriginalStringUri.AbsoluteUri 与 Uri.OriginalString
【发布时间】:2018-08-06 14:04:05
【问题描述】:

我最近意识到Uri.ToString() 的奇怪行为(即,它取消了一些字符的编码,因此主要适用于显示目的)。我试图在 AbsoluteUriOriginalString 之间做出决定,作为我将 Uri 对象转换为字符串的“首选”(例如,在剃刀视图中)。

到目前为止,我发现两者之间的唯一区别是 AbsoluteUri 对于相对 uri 将失败(例如 new Uri("foo", UriKind.Relative).AbsoluteUri)。这似乎支持OriginalString。但是,我对“原始”这个词感到担忧,因为它表明某些内容可能无法正确编码或转义。

谁能确认这两个属性之间的区别(除了我发现的一个区别)?

【问题讨论】:

    标签: c# .net uri url-encoding


    【解决方案1】:

    我一直喜欢OriginalString,因为我遇到了AbsoluteUri 的多个问题。即:

    AbsoluteUri 在 .NET 4.0 和 .NET 4.5 中的行为不同 (see)

    .NET 框架 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 框架 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 不支持相对 URI

    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 会进行不必要的转义

    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
    

    【讨论】:

    • 关于最后一点,http://www.example.com/test.aspx?v=hello%20world 是一个有效的 URL,因为空格必须是转义的。 OriginalString 提供了仅适合查看的无效 URL
    • 我没说无效;我说这是错误,至少在这个问题的上下文中。我故意使用无效的 URL 来突出差异;作者谈到 Uri.ToString() 解码一些字符。 AbsoluteUri 也受此影响,除了它编码 一些字符。如果您想要原始的、未更改的 URL(例如……用于实例化手头的 Uri 对象的 URL,没有编码,也没有解码),OriginalString 提供了这一点。如果这个 URL 无效,我宁愿首先找出它是如何到达那里的,而不是让 AbsoluteUri 掩盖它。
    • "example.com/test%2F1" 看起来不像一个有效的 url,期望查询参数只被编码。如果我错了,请纠正我
    • example.com/test%2F1 不包含任何无效字符,因此它有效的 URL。虽然查询字符串是最常见的用法,但 URL 编码并不限于此。根据MDNpercent-encoding 是一种编码 8 位字符的机制,在 URL 的上下文中具有特定含义。
    【解决方案2】:

    规范化是使用AbsoluteUri 而不是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
    

    【讨论】:

    【解决方案3】:

    为了将 Uri 对象转换为我使用的字符串

    Location.ToString().StripQuotes();
    

    请注意,ToString 生成的 url 字符串用双引号 ",我必须使用来自 Flurl/src/Flurl/Util/CommonExtensions.cs 的 StripQuotes 删除它们

    另请参阅MSDN example,它说明了从 OriginalString 返回的值(返回传递给构造函数的字符串)与调用 ToString(返回字符串的规范形式)之间的差异。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-23
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 2015-12-10
      • 2010-09-07
      相关资源
      最近更新 更多