網址列常見 %E9%AB%98%E6%B8%85%E6%99%B0 這類百分號編碼(Percent-Encoding),對應 UTF-8 位元組序列。ASP.NET 內建 Server.UrlDecode、HttpUtility.UrlDecode、Uri.UnescapeDataString 等方法,但行為略有不同。本文釐清差異並示範正確解碼中文 URL 路徑與查詢字串。
%XX 形式(XX 為十六進位位元組)。E9 AB 98 E6 B8 85 E6 99 B0 → %E9%AB%98%E6%B8%85%E6%99%B0。%20 或 +(查詢字串習慣)。| 方法 | 命名空間 | 處理 + 號 | 適用場景 | 備註 |
|---|---|---|---|---|
| Server.UrlDecode | System.Web | + → 空白 | 查詢字串 Request.QueryString | 內部呼叫 HttpUtility.UrlDecode |
| HttpUtility.UrlDecode | System.Web | + → 空白 | 一般查詢字串、表單資料 | 支援指定 Encoding |
| Uri.UnescapeDataString | System | 不轉換 + 號 | URL 路徑片段、完整 URL | 符合 RFC 3986,.NET Core 推薦 |
// 查詢字串:name=%E9%AB%98%E6%B8%85%E6%99%B0
string q = Request.QueryString["name"]; // 自動 UrlDecode → "高清晰"
// 路徑片段:/search/%E9%AB%98%E6%B8%85%E6%99%B0
string rawPath = Request.Path; // 原始編碼路徑
// 錯誤做法
string wrong = Server.UrlDecode(rawPath); // 會把路徑中合法的 + 變空白
// 正確做法
string correct = Uri.UnescapeDataString(rawPath); // 保留 +,正確解碼中文
using System;
public class UrlDecoder
{
public static string DecodeUrlPath(string encodedPath)
{
if (string.IsNullOrEmpty(encodedPath)) return encodedPath;
try
{
// Uri.UnescapeDataString 正確處理 UTF-8 多位元組序列
return Uri.UnescapeDataString(encodedPath);
}
catch (UriFormatException)
{
// 非法編碼序列(如 %GG)拋出例外,回傳原字串或拋出自訂例外
return encodedPath;
}
}
// 解碼完整 URL 但保留結構
public static string DecodeFullUrlPreservingStructure(string fullUrl)
{
if (string.IsNullOrEmpty(fullUrl)) return fullUrl;
var uri = new Uri(fullUrl);
// 僅解碼 Path 和 Fragment,Query 由 HttpUtility.ParseQueryString 處理
string decodedPath = Uri.UnescapeDataString(uri.AbsolutePath);
string decodedFragment = uri.Fragment.Length > 0 ? Uri.UnescapeDataString(uri.Fragment) : "";
return $"{uri.Scheme}://{uri.Authority}{decodedPath}{uri.Query}{decodedFragment}";
}
}
// 使用範例
string encoded = "/product/%E9%AB%98%E6%B8%85%E6%99%B0/detail?id=123";
string decoded = UrlDecoder.DecodeUrlPath(encoded);
// 結果:/product/高清晰/detail?id=123
Java 使用 java.net.URLDecoder.decode(String, "UTF-8"),行為類似 HttpUtility.UrlDecode(+ → 空白)。路徑解碼需自行處理或使用 java.net.URI 類別。
Request.QueryString 已自動解碼,再次呼叫 UrlDecode 會導致 %25 (編碼後的 %) 再次解碼產生錯誤。HttpUtility.UrlDecode(str, Encoding.GetEncoding("big5"))。Uri.UnescapeDataString 解碼路由參數,Action 參數直接獲得解碼後字串。Uri.EscapeDataString (路徑)、HttpUtility.UrlEncode (查詢字串)。記住核心原則:查詢字串用 HttpUtility.UrlDecode,URL 路徑用 Uri.UnescapeDataString。ASP.NET MVC/Core 開發者幾乎不需手動解碼,框架已在模型繫結階段正確處理。僅在處理原始 URL 字串、舊系統整合、自訂路由時需直接呼叫此方法。