首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET URL 編碼與解碼:Uri.UnescapeDataString 正確處理中文路徑參數

     編輯:關於ASP.NET

網址列常見 %E9%AB%98%E6%B8%85%E6%99%B0 這類百分號編碼(Percent-Encoding),對應 UTF-8 位元組序列。ASP.NET 內建 Server.UrlDecode、HttpUtility.UrlDecode、Uri.UnescapeDataString 等方法,但行為略有不同。本文釐清差異並示範正確解碼中文 URL 路徑與查詢字串。

編碼原理快速回顧

  • URL 僅允許 ASCII 字元,非 ASCII 需轉為 %XX 形式(XX 為十六進位位元組)。
  • 中文「高清晰」UTF-8 編碼為 3 個字元 × 3 位元組 = 9 位元組:E9 AB 98 E6 B8 85 E6 99 B0 → %E9%AB%98%E6%B8%85%E6%99%B0。
  • 空白編碼為 %20 或 +(查詢字串習慣)。

三種解碼方法比較

方法命名空間處理 + 號適用場景備註
Server.UrlDecodeSystem.Web+ → 空白查詢字串 Request.QueryString內部呼叫 HttpUtility.UrlDecode
HttpUtility.UrlDecodeSystem.Web+ → 空白一般查詢字串、表單資料支援指定 Encoding
Uri.UnescapeDataStringSystem不轉換 + 號URL 路徑片段、完整 URL符合 RFC 3986,.NET Core 推薦

關鍵差異:路徑 vs 查詢字串

// 查詢字串: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); // 保留 +,正確解碼中文

完整範例:解碼完整 URL 中的中文路徑

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 使用 java.net.URLDecoder.decode(String, "UTF-8"),行為類似 HttpUtility.UrlDecode(+ → 空白)。路徑解碼需自行處理或使用 java.net.URI 類別。

常見陷阱與最佳實踐

  • 雙重解碼:Request.QueryString 已自動解碼,再次呼叫 UrlDecode 會導致 %25 (編碼後的 %) 再次解碼產生錯誤。
  • 編碼不一致:舊系統可能用 Big5/GB2312 編碼 URL,解碼時需指定 HttpUtility.UrlDecode(str, Encoding.GetEncoding("big5"))。
  • 路由參數自動解碼:ASP.NET MVC / Core 路由模型繫結器會自動 Uri.UnescapeDataString 解碼路由參數,Action 參數直接獲得解碼後字串。
  • 建構 URL 時請編碼:Uri.EscapeDataString (路徑)、HttpUtility.UrlEncode (查詢字串)。

結語

記住核心原則:查詢字串用 HttpUtility.UrlDecode,URL 路徑用 Uri.UnescapeDataString。ASP.NET MVC/Core 開發者幾乎不需手動解碼,框架已在模型繫結階段正確處理。僅在處理原始 URL 字串、舊系統整合、自訂路由時需直接呼叫此方法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved