Câu trả lời:
HttpServerUtility.UrlEncode
sẽ sử dụng HttpUtility.UrlEncode
nội bộ. Không có sự khác biệt cụ thể. Lý do cho sự tồn tại của Server.UrlEncode
là khả năng tương thích với ASP cổ điển.
Tôi đã bị đau đầu đáng kể với các phương pháp này trước đây, tôi khuyên bạn nên tránh mọi biến thể của UrlEncode
, và thay vào đó hãy sử dụngUri.EscapeDataString
- ít nhất là một phương pháp có hành vi dễ hiểu.
Hãy xem nào...
HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
//standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
// want, since you still need to
// escape special characters yourself
Nhưng sở thích cá nhân của tôi phải là httpUtility.UrlPathEncode - điều này thực sự không thể hiểu được. Nó mã hóa:
Nó cũng có tài liệu MSDN cụ thể đáng yêu "Mã hóa phần đường dẫn của chuỗi URL để truyền HTTP đáng tin cậy từ máy chủ Web đến máy khách." - mà không thực sự giải thích những gì nó làm. Bạn ít có khả năng tự bắn vào chân mình bằng một khẩu Uzi ...
Nói tóm lại, hãy bám lấy Uri.EscapeDataString .
?
người và ai sẽ nói cái nào được mã hóa và cái nào dùng làm dấu phân cách? Về không gian: trong cả hai trường hợp, khoảng trắng nằm trong hàm băm, do đó, sự hiện diện hay vắng mặt của một đoạn truy vấn không quan trọng. Và cuối cùng, không thể tha thứ cho một Uri như trong ví dụ thứ hai chứa%. Các UrlPathEncode
phương pháp được đơn giản borked và không bao giờ nên được sử dụng.
Chuyển tiếp nhanh gần 9 năm kể từ lần đầu tiên được hỏi và trong thế giới của .NET Core và .NET Standard, có vẻ như các tùy chọn phổ biến nhất chúng tôi có để mã hóa URL là WebUtility.UrlEncode (bên dướiSystem.Net
) và Uri.EscapeDataString . Đánh giá bằng câu trả lời phổ biến nhất ở đây và ở nơi khác, Uri.EscapeDataString dường như được ưa thích hơn. Nhưng nó là? Tôi đã thực hiện một số phân tích để hiểu sự khác biệt và đây là những gì tôi nghĩ ra:
WebUtility.UrlEncode
mã hóa không gian như +
; Uri.EscapeDataString
mã hóa nó thành %20
.Uri.EscapeDataString
mã hóa phần trăm !
, (
, )
, và *
; WebUtility.UrlEncode
không làm.WebUtility.UrlEncode
mã hóa phần trăm ~
; Uri.EscapeDataString
không làm.Uri.EscapeDataString
ném một UriFormatException
chuỗi dài hơn 65.520 ký tự; WebUtility.UrlEncode
không làm. ( Một vấn đề phổ biến hơn bạn nghĩ, đặc biệt là khi xử lý dữ liệu biểu mẫu được mã hóa URL .)Uri.EscapeDataString
ném một UriFormatException
trên ký tự đại diện cao ; WebUtility.UrlEncode
không làm. (Đó là một điều UTF-16, có lẽ ít phổ biến hơn nhiều.)Đối với mục đích mã hóa URL, các ký tự phù hợp với một trong 3 loại: không được giám sát (hợp pháp trong một URL); dành riêng (hợp pháp trong nhưng có ý nghĩa đặc biệt, vì vậy bạn có thể muốn mã hóa nó); và mọi thứ khác (phải luôn được mã hóa).
Theo RFC , các ký tự dành riêng là::/?#[]@!$&'()*+,;=
Và các ký tự không được giám sát là chữ và số -._~
Uri.EscapeDataString xác định rõ nhiệm vụ của mình:% -encode tất cả các ký tự được bảo lưu và bất hợp pháp. WebUtility.UrlEncode mơ hồ hơn trong cả định nghĩa và triển khai. Điều kỳ lạ là, nó mã hóa một số ký tự dành riêng nhưng không phải là ký tự khác (tại sao dấu ngoặc đơn và không phải dấu ngoặc ??), và người lạ vẫn mã hóa nó một cách vô tư~
ký tự .
Do đó, tôi đồng tình với lời khuyên phổ biến - sử dụng Uri.EscapeDataString khi có thể và hiểu rằng các ký tự dành riêng như /
và ?
sẽ được mã hóa. Nếu bạn cần xử lý các chuỗi có khả năng lớn, đặc biệt là với nội dung biểu mẫu được mã hóa URL, bạn sẽ cần phải quay lại WebUtility.UrlEncode và chấp nhận các yêu cầu của nó hoặc giải quyết vấn đề khác.
EDIT: Tôi đã cố gắng để khắc phục TẤT CẢ những khuyết tật nêu trên trong Flurl qua Url.Encode
, Url.EncodeIllegalCharacters
và Url.Decode
phương pháp tĩnh. Các gói này nằm trong gói lõi (rất nhỏ và không bao gồm tất cả nội dung HTTP) hoặc thoải mái trích xuất chúng từ nguồn. Tôi hoan nghênh bất kỳ ý kiến / phản hồi bạn có về những điều này.
Đây là mã tôi đã sử dụng để khám phá các ký tự được mã hóa khác nhau:
var diffs =
from i in Enumerable.Range(0, char.MaxValue + 1)
let c = (char)i
where !char.IsHighSurrogate(c)
let diff = new {
Original = c,
UrlEncode = WebUtility.UrlEncode(c.ToString()),
EscapeDataString = Uri.EscapeDataString(c.ToString()),
}
where diff.UrlEncode != diff.EscapeDataString
select diff;
foreach (var diff in diffs)
Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
Hãy nhớ rằng bạn có thể không nên sử dụng một trong những phương pháp đó. Thư viện kịch bản trang web chống chéo của Microsoft bao gồm các thay thế HttpUtility.UrlEncode
và HttpUtility.HtmlEncode
cả hai đều tuân thủ tiêu chuẩn hơn và an toàn hơn. Như một phần thưởng, bạn cũng có được một JavaScriptEncode
phương pháp.