Yanıtlar:
HttpServerUtility.UrlEncode
HttpUtility.UrlEncode
dahili olarak kullanır . Belirli bir fark yok. Varlığının nedeni Server.UrlEncode
klasik ASP ile uyumluluktur.
Daha önce bu yöntemlerle önemli baş ağrılarım vardı , en azından birinin anlaşılabilir bir davranışı olduğu için herhangi bir varyanttan kaçınmanızı ve kullanmanızı öneriyorumUrlEncode
Uri.EscapeDataString
.
Bakalım...
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
Ama benim kişisel favorim HttpUtility.UrlPathEncode olmalı - bu şey gerçekten anlaşılmaz. Kodlar:
Ayrıca, "Web sunucusundan bir istemciye güvenilir HTTP iletimi için bir URL dizesinin yol bölümünü kodlar." - aslında ne yaptığını açıklamadan. Kendinizi bir Uzi ile ayağa vurmanız daha az olasıdır ...
Kısacası Uri.EscapeDataString öğesine sadık kalın .
?
ve hangilerinin kodlanacağını ve hangilerinin ayırıcı olarak işlev göreceğini kim söyleyebilir? Alanla ilgili olarak: her iki durumda da alan karmadır, bu nedenle bir sorgu parçasının varlığı veya yokluğu önemli olmamalıdır. Ve son olarak,% içeren ikinci örnekteki gibi bir Uri'yi bozmak mümkün değildir. UrlPathEncode
Yöntem düz sorunludur ve asla kullanılmamalıdır.
Bu ilk sorulduğundan beri neredeyse 9 yıl ileri gidin ve .NET Core ve .NET Standard dünyasında, URL kodlaması için en yaygın seçenekler WebUtility.UrlEncode (altında System.Net
) ve Uri.EscapeDataString . Buradaki ve diğer yerlerdeki en popüler cevaba bakarak , Uri.EscapeDataString tercih edilebilir gibi görünüyor. Ama öyle mi? Farklılıkları anlamak için bazı analizler yaptım ve işte ne ile geldi:
WebUtility.UrlEncode
alanı şu şekilde kodlar +
; Uri.EscapeDataString
olarak kodlar %20
.Uri.EscapeDataString
yüzde kodlar !
, (
, )
ve *
; WebUtility.UrlEncode
değil.WebUtility.UrlEncode
yüzde kodlamaları ~
; Uri.EscapeDataString
değil.Uri.EscapeDataString
UriFormatException
65.520 karakterden daha uzun dizelere atar ; WebUtility.UrlEncode
değil. ( Özellikle URL kodlu form verileriyle uğraşırken düşündüğünüzden daha yaygın bir sorun .)Uri.EscapeDataString
Bir atar UriFormatException
üzerine yüksek vekil karakterler ; WebUtility.UrlEncode
değil. (Bu UTF-16 bir şey, muhtemelen çok daha az yaygın.)URL kodlama amacıyla, karakterler 3 kategoriden birine girer: kaydedilmemiş (bir URL'de yasal); (yasal ancak bunu, özel bir anlamı vardır saklıdır olabilir bunu kodlamak istiyorum); ve diğer her şey (her zaman kodlanmalıdır).
RFC'ye göre , ayrılmış karakterler::/?#[]@!$&'()*+,;=
Ve kaydedilmemiş karakterler alfasayısal ve -._~
Uri.EscapeDataString görevini açıkça tanımlar:% -encode tüm ayrılmış ve yasadışı karakterleri. WebUtility.UrlEncode hem tanım hem de uygulama açısından daha belirsizdir. Garip bir şekilde, bazı ayrılmış karakterleri kodlar, ancak diğerlerini değil (neden parantez ve parantez değil ??) ve yabancı hala masumca korunmayan ~
karakteri kodlar .
Bu nedenle, popüler tavsiye ile hemfikirim - mümkünse Uri.EscapeDataString'i kullanın ve ayrılmış karakterlerin gibi /
ve ?
şifreleneceğini anlayın . Potansiyel olarak büyük dizelerle, özellikle URL kodlu form içeriğiyle ilgilenmeniz gerekiyorsa, ya WebUtility.UrlEncode'a geri dönüp kabul etmelisiniz ya da sorunu başka şekilde çözmelisiniz .
DÜZENLEME: Ben ettik teşebbüs TÜM yukarıda belirtilen garipliklerilistesinde düzeltmek için Flurl yoluyla Url.Encode
, Url.EncodeIllegalCharacters
ve Url.Decode
statik yöntemlerle. Bunlar çekirdek pakette (küçüktür ve tüm HTTP öğelerini içermez) veya kaynaktan kopyalamaktan çekinmeyin. Bunlar hakkında herhangi bir yorum / geribildirim hoş geldiniz.
İşte hangi karakterlerin farklı kodlandığını keşfetmek için kullandığım kod:
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}");
Muhtemelen bu yöntemlerden birini kullanmamanız gerektiğini unutmayın. Microsoft'un anti-Cross Site Scripting Kütüphanesi için değiştirmeler içerir HttpUtility.UrlEncode
ve HttpUtility.HtmlEncode
hem daha standartlarla uyumlu ve daha güvenli olmasını. Bir bonus olarak, bir JavaScriptEncode
yöntem de alırsınız .