January 14, 2010

HttpUtility.UrlEncode, HttpUtility.UrlPathEncode, HttpServerUtility.UrlEncode及HttpServerUtility.UrlPathEncode

在網路上看了官方資料和一些其它網友的比較說明,在這做個紀錄

以下是MSDN針對這四個function做的說明
HttpUtility.UrlEncode HttpUtility.UrlPathEncode
Server.UrlEncode Server.UrlPathEncode

大略說明一下它們之間的差異
  1. HttpUtility.UrlEncode預設是使用UTF8編碼,而Server.UrlEncode是使用系統預設編碼;Server.UrlEncode會使用系統預設編碼做為參數代入並呼叫HttpUtility.UrlEncode做編碼動作,這點可由.NET Reflector來驗証
  2. Server.UrlPathEncode會呼叫HttpUtility.UrlEncode做編碼動作,而HttpUtility.UrlEncode預設使用UTF8編碼,所以Server.UrlPathEncode會以UTF8編碼,這點可由.NET Reflector來驗証
  3. HttpUtility.UrlEncode將空格編碼為+,而HttpUtility.UrlPathEncode將空格編碼為%20
  4. HttpUtility.UrlEncode會針對完整的URL做編碼,包含Query String;Server.UrlPathEncode則不對Query String做編碼
  5. HttpUtility.UrlEncode及HttpUtility.UrlPathEncode為靜態函式,而Server.UrlEncode及Server.UrlPathEncode需在ASP.NET中以Page.Server(或直接以Server)取得HttpServerUtility物件後才可以使用[註1]
  6. HttpUtility.UrlEncode會針對冒號(:)斜線(/)做編碼,如http://會編碼成http%3a%2f%2f。所以HttpUtility.UrlEncode不宜對URL的路徑部份做編碼,以免執行如Response.Rediret功能時,無法導向正確網址,應改由HttpUtility.UrlPathEncode對URL路徑部份做編碼[註2]

測試範例

UrlEncodeTest.aspx
 <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Redirect to UrlEncodeTest.aspx using HttpUtility.UrlEncode" />
 <p>
 <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Redirect to UrlEncodeTest.aspx using HttpUtility.UrlPathEncode" />
 </p>
 <p>
 <asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="Redirect to UrlEncodeTest.aspx?param1=參數值1&amp;param2=value2 using HttpUtility.UrlEncode" />
 </p>
 <p>
 <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" Text="Redirect to UrlEncodeTest.aspx?param1=參數值1&amp;param2=value2 using HttpUtility.UrlPathEncode" />
 </p>
 <p>
 <asp:Button ID="Button5" runat="server" OnClick="Button5_Click" Text="Redirect to UrlEncodeTest.aspx?param=我 是 空 白 using HttpUtility.UrlEncode" />
 </p>
 <p>
 <asp:Button ID="Button6" runat="server" OnClick="Button6_Click" Text="Redirect to UrlEncodeTest.aspx?param=我 是 空 白 using HttpUtility.UrlPathEncode" />
 </p>

UrlEncodeTest.aspx.cs
private string url = "http://localhost:10710/UrlEncodeTest.aspx";

protected void Page_Load(object sender, EventArgs e)
{
    if(!string.IsNullOrEmpty(Request.QueryString["param"]))
    {
        Response.Write(Request.QueryString["param"] + "<br>");
    }

    if(!string.IsNullOrEmpty(Request.QueryString["param1"]))
    {
        Response.Write(Request.QueryString["param1"] + "<br>");
    }

    if(!string.IsNullOrEmpty(Request.QueryString["param2"]))
    {
        Response.Write(Request.QueryString["param2"] + "<br>");
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    Response.Redirect(HttpUtility.UrlEncode(url));
}

protected void Button2_Click(object sender, EventArgs e)
{
    Response.Redirect(HttpUtility.UrlPathEncode(url));
}

protected void Button3_Click(object sender, EventArgs e)
{
    url += "?param1=參數值1&param2=value2";
    Response.Redirect(HttpUtility.UrlEncode(url));
}

protected void Button4_Click(object sender, EventArgs e)
{
    url += "?param1=參數值1&param2=value2";
    Response.Redirect(HttpUtility.UrlPathEncode(url));
}

protected void Button5_Click(object sender, EventArgs e)
{
    url += "?param=我 是 空 白";
    Response.Redirect(HttpUtility.UrlEncode(url));
}

protected void Button6_Click(object sender, EventArgs e)
{
    url += "?param=我 是 空 白";
    Response.Redirect(HttpUtility.UrlPathEncode(url));
}

備註
  1. 當然,您也可以在類別庫專案中以HttpContext物件來取得HttpServerUtility,如System.Web.HttpContext.Current.Server
  2. 小弟在研究MSDN時發現Server.UrlPathEncode的範例似乎有誤,測試發現Server.UrlPathEncode並不會對冒號(:)或斜線(/)做編碼,而範例顯示是會編碼的