Jawaban:
HttpServerUtility.UrlEncode
akan digunakan secara HttpUtility.UrlEncode
internal. Tidak ada perbedaan khusus. Alasan adanya Server.UrlEncode
kompatibilitas 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 UrlPathEncode
Metode 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.UrlEncode
mengkodekan ruang sebagai +
; Uri.EscapeDataString
mengkodekannya sebagai %20
.Uri.EscapeDataString
persen-mengkodekan !
, (
, )
, dan *
; WebUtility.UrlEncode
tidak.WebUtility.UrlEncode
persen-encode ~
; Uri.EscapeDataString
tidak.Uri.EscapeDataString
melempar UriFormatException
string lebih dari 65.520 karakter; WebUtility.UrlEncode
tidak. ( Masalah yang lebih umum daripada yang mungkin Anda pikirkan, terutama ketika berhadapan dengan data formulir yang disandikan URL .)Uri.EscapeDataString
melempar UriFormatException
pada karakter pengganti tinggi ; WebUtility.UrlEncode
tidak. (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.EncodeIllegalCharacters
dan Url.Decode
metode 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.UrlEncode
dan HttpUtility.HtmlEncode
yang keduanya lebih sesuai standar, dan lebih aman. Sebagai bonus, Anda mendapatkan JavaScriptEncode
metode juga.