Jawaban:
HttpServerUtility.UrlEncodeakan digunakan secara HttpUtility.UrlEncodeinternal. Tidak ada perbedaan khusus. Alasan adanya Server.UrlEncodekompatibilitas dengan ASP klasik.
Saya mengalami sakit kepala yang signifikan dengan metode-metode ini sebelumnya, saya sarankan Anda menghindari varian apa pun UrlEncode, dan alih-alih menggunakanUri.EscapeDataString - paling tidak seseorang memiliki perilaku yang dapat dipahami.
Ayo lihat...
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
Tetapi favorit pribadi saya harus menjadi HttpUtility.UrlPathEncode - hal ini benar-benar tidak dapat dipahami. Ini mengkodekan:
Ia juga memiliki dokumentasi MSDN yang sangat spesifik "Mengkodekan bagian jalur dari string URL untuk transmisi HTTP yang andal dari server Web ke klien." - tanpa benar-benar menjelaskan apa fungsinya. Anda cenderung menembak diri sendiri di kaki dengan ...
Singkatnya, tetap menggunakan Uri.EscapeDataString .
?dan siapa yang mengatakan yang harus dikodekan dan yang berfungsi sebagai pemisah? Adapun ruang: dalam kedua kasus ruang di hash, sehingga ada atau tidak adanya fragmen kueri seharusnya tidak masalah. Dan akhirnya, tidak dapat dimaafkan untuk merusak Uri seperti pada contoh kedua yang berisi%. The UrlPathEncodeMetode ini polos borked dan tidak boleh digunakan.
Maju cepat hampir 9 tahun sejak ini pertama kali ditanyakan, dan di dunia .NET Core dan .NET Standard, sepertinya opsi yang paling umum yang kita miliki untuk pengkodean URL adalah WebUtility.UrlEncode (di bawah System.Net) dan Uri.EscapeDataString . Dilihat oleh jawaban paling populer di sini dan di tempat lain, Uri.EscapeDataString tampaknya lebih disukai. Tetapi apakah itu? Saya melakukan beberapa analisis untuk memahami perbedaan dan inilah yang saya temukan:
WebUtility.UrlEncodemengkodekan ruang sebagai +; Uri.EscapeDataStringmengkodekannya sebagai %20.Uri.EscapeDataStringpersen-mengkodekan !, (, ), dan *; WebUtility.UrlEncodetidak.WebUtility.UrlEncodepersen-encode ~; Uri.EscapeDataStringtidak.Uri.EscapeDataStringmelempar UriFormatExceptionstring lebih dari 65.520 karakter; WebUtility.UrlEncodetidak. ( Masalah yang lebih umum daripada yang mungkin Anda pikirkan, terutama ketika berhadapan dengan data formulir yang disandikan URL .)Uri.EscapeDataStringmelempar UriFormatExceptionpada karakter pengganti tinggi ; WebUtility.UrlEncodetidak. (Itu hal UTF-16, mungkin jauh lebih umum.)Untuk keperluan pengkodean URL, karakter sesuai dengan salah satu dari 3 kategori: tidak dapat diterima (legal dalam URL); dilindungi undang-undang (legal tetapi memiliki makna khusus, jadi Anda mungkin ingin menyandikannya); dan yang lainnya (harus selalu dikodekan).
Menurut RFC , karakter yang dipesan adalah::/?#[]@!$&'()*+,;=
Dan karakter tanpa syarat adalah alfanumerik dan -._~
Uri.EscapeDataString dengan jelas mendefinisikan misinya:% -encode semua karakter yang dilindungi undang-undang dan ilegal. WebUtility.UrlEncode lebih ambigu dalam definisi dan implementasi. Anehnya, itu mengkodekan beberapa karakter yang dilindungi undang-undang tetapi tidak yang lain (mengapa tanda kurung dan bukan tanda kurung ??), dan orang asing masih mengkode ~karakter yang tidak bersalah .
Oleh karena itu, saya setuju dengan saran populer - gunakan Uri.EscapeDataString bila memungkinkan, dan pahami bahwa karakter yang dicadangkan suka /dan ?akan disandikan. Jika Anda perlu berurusan dengan string yang berpotensi besar, terutama dengan konten formulir yang disandikan URL, Anda harus kembali ke WebUtility.UrlEncode dan menerima kebiasaannya, atau mengatasi masalah tersebut.
EDIT: Saya sudah berusaha untuk memperbaiki SEMUA kebiasaan yang disebutkan di atas di Flurl melalui Url.Encode, Url.EncodeIllegalCharactersdan Url.Decodemetode statis. Ini ada dalam paket inti (yang kecil dan tidak termasuk semua barang HTTP), atau merasa bebas untuk mengambilnya dari sumbernya. Saya menyambut setiap komentar / umpan balik yang Anda miliki tentang ini.
Berikut kode yang saya gunakan untuk menemukan karakter mana yang dikodekan secara berbeda:
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}");
Ingatlah bahwa Anda sebaiknya tidak menggunakan salah satu dari metode tersebut. Perpustakaan Scripting Situs Anti-Lintas Microsoft mencakup penggantian untuk HttpUtility.UrlEncodedan HttpUtility.HtmlEncodeyang keduanya lebih sesuai standar, dan lebih aman. Sebagai bonus, Anda mendapatkan JavaScriptEncodemetode juga.