當心 Request.Url.ToString() 傳回無效 URL

抓到一個誤用 Request.Url.ToString() 造成的 Bug。

由使用者回報錯誤,追出某段程式擷取 Request.Url.ToString() 加工產生的連結有誤。 原本 URL 參數包含另一頁網址,依規定做了 UrlEncode,如: b=http%3A//blog2.darkthread.net%3Fm%3D1%26a%3D456 。ASP.NET 程式抓取 Request.Url.ToString() 修改後串接額外參數"&a=ABC",得到的結果卻是 b=httq://blog2.darkthread.net/?m=1&a=456&a=ABC [註: 此處改成 httq 是為防止被當成可連結網址],也因此,接收網頁抓取的 a 變成 456,ABC。

實測後發現,我一直誤認 Request.Url.ToString() 傳回的會是 URL 原始字串(就是瀏覽器地址欄顯示的字串內容),事實不然,來看一個測試:

依據 MSDN 文件

The value returned by this property differs from ToString and AbsoluteUri. ToString returns the canonically unescaped form of the URI. AbsoluteUri returns the canonically escaped form of the URI.

要將 Uri 型別轉為字串,ToString()AbsoluteUriOriginalString 都是選項,但意義與用途不同。

Uri.ToString() 傳回的是 URI 以標準方式未逸出處理(Unescaped)過的版本
Uri.AbsoluteUri 傳回的則是 URI 以標準方式逸出處理(Escaped)過的版本
Uri.OriginalString 則是未經處理的原始版本(OriginalString 序列化後不會保留)

換言之,OriginalString 是建構物件時所提供的字串參數,原汁原味連不符規範的部分也都保留;ToString() 及 AbsoluteUri 則為標準化處理過的版本, ToString() 為方便人類閱讀將 %XX 編碼還原回字元,但可能因此不符合 URL 規範,用於瀏覽器可能會出錯(就如本案例); AbsoluteUri 產生的結果則力求符合規範,遺漏 UrlEncode 的部分也會補上,例如以下範例:

var uri = new Uri("http://blog2.darkthread.net?a=a c"); //參數空白未編碼 
Debug.WriteLine(uri.AbsoluteUri); //會轉為http://blog2.darkthread.net/?a=a%20c

在本案例中,AbsoluteUri 是較佳選擇,而實務上應避免使用 ToString(),以免產生無效 URL。

歡迎推文分享:
Published 07 March 2018 10:54 PM 由 Jeffrey
Filed under:
Views: 4,219



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<March 2018>
SunMonTueWedThuFriSat
25262728123
45678910
11121314151617
18192021222324
25262728293031
1234567
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication