Server.UrlEncode ve HttpUtility.UrlEncode karşılaştırması


177

Server.UrlEncode ve HttpUtility.UrlEncode arasında bir fark var mı?

Yanıtlar:


133

HttpServerUtility.UrlEncodeHttpUtility.UrlEncodedahili olarak kullanır . Belirli bir fark yok. Varlığının nedeni Server.UrlEncodeklasik ASP ile uyumluluktur.


3
Kaçan şey gelince. Dahili olarak bu işlevi
Jeff

Okuyucular için: Lütfen aşağıdaki Joel Muller cevabına bakınız. URL kodlamanın en etkili yolu budur: stackoverflow.com/a/603962/190476
Sudhanshu Mishra

264

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ı öneriyorumUrlEncodeUri.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:

  • "" ==> "% 20"
  • "100% true" ==> "100 %% 20true" (tamam, URL'niz şimdi bozuldu)
  • "test A.aspx # çapa B" ==> "test% 20A.aspx # çapa% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( önceki kaçış dizisiyle farkı not edin! )

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 .


4
Ve ne yazık ki bu bazı web sunucularına karşı HTTP istekleri yaparken hala çalışmıyor - Uri.EscapeDataString () "!" veya "("), escape () tarayıcı uygulamalarının çoğunun çalışma biçiminden farklı ...
Chris R. Donnelly

6
! ve 'karakterlerin kodlanması gerekmez; ancak buggy web sunucusu bunu gerektiriyorsa, bu sorunu çözmek kolaydır. Javascript'in kaçış işlevinden kaçının - doğası gereği buggy (biri için gidiş dönüş imkansız). Bkz. Xkr.us/articles/javascript/encode-compare - ama kısaca; bunun yerine EscapeDataString'e benzer şekilde çalışan encodeUriComponent () öğesini kullanabilirsiniz - tahmin edilebilir ve geri dönüşümlü olarak bir dizeyi kodlar ve kodlamaz! ve 'karakterleri.
Eamon Nerbonne

2
Bu eski, ancak soru ön sayfaya çarptı, bu yüzden .... Bir url dizesinin yol kısmı, etki alanı ve? veya bir url'de #.
Powerlord

2
@Tim: Birkaç tane olabilir ?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. UrlPathEncodeYöntem düz sorunludur ve asla kullanılmamalıdır.
Eamon Nerbonne

1
Stackoverflow.com/a/13993486/237091 adresindeki yanıtımın, UrlEncode / UrlPathEncode'un kullanım amacına biraz ışık tutabileceğini düşünüyorum .
Scott Stafford

60

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.UrlEncodealanı şu şekilde kodlar +; Uri.EscapeDataStringolarak kodlar %20.
  • Uri.EscapeDataStringyüzde kodlar !, (, )ve *; WebUtility.UrlEncodedeğil.
  • WebUtility.UrlEncodeyüzde kodlamaları ~; Uri.EscapeDataStringdeğil.
  • Uri.EscapeDataStringUriFormatException65.520 karakterden daha uzun dizelere atar ; WebUtility.UrlEncodedeğil. ( Özellikle URL kodlu form verileriyle uğraşırken düşündüğünüzden daha yaygın bir sorun .)
  • Uri.EscapeDataStringBir atar UriFormatExceptionüzerine yüksek vekil karakterler ; WebUtility.UrlEncodedeğ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 -._~

Karar

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.EncodeIllegalCharactersve Url.Decodestatik 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}");

2
Bu harika!
Jorge Aguirre

1
Modern .net çerçevesinde önerilen çözümü doğrulayan harika bir iş.
Neowizard

WebUtility ve HttpUtility arasında bazı farklılıklar olduğu belirtilmelidir . WebUtility büyük harf ve HttpUtility hexa varlıkları için küçük harf kullanıyor. Ayrıca, HttpUtility .NET Framework "İstemci Profili" nin eski alt küme sürümlerine dahil edilmemiştir. WebUtility .NET Framework 4.0'dan edinilebilir.
tibx

28

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.UrlEncodeve HttpUtility.HtmlEncodehem daha standartlarla uyumlu ve daha güvenli olmasını. Bir bonus olarak, bir JavaScriptEncodeyöntem de alırsınız .


Verilen bağlantıdaki belgeleri ve SSS'yi okuduktan sonra, bu cevabın veri kodlamanın en iyi ve en güvenli yolu olduğuna inanıyorum! Bunu paylaştığın için teşekkürler!
Sudhanshu Mishra

Bağlantı artık çalışmıyor. Değiştirme yöntemleri nelerdir?
Edward Brey

@EdwardBrey Bu, Anti-Cross site komut dosyası kitaplığının en son sürümüdür: microsoft.com/en-au/download/details.aspx?id=28589
Sudhanshu Mishra

11

Server.UrlEncode (), Klasik ASP ile geriye dönük uyumluluk sağlamak için vardır,

Server.UrlEncode(str);

Şuna eşittir:

HttpUtility.UrlEncode(str, Response.ContentEncoding);

5

Aynı, Server.UrlEncode()çağrılarHttpUtility.UrlEncode()

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.