Yanıtlar:
EscapeDataStringHer zaman kullanın (neden hakkında daha fazla bilgi için aşağıdaki Livven'in cevabına bakın)
Düzenleme : iki kodlama farklı nasıl ölü bağlantı kaldırıldı
URLEncode).
Mevcut cevapları tatmin edici bulamadım, bu yüzden bu sorunu çözmek için biraz daha derine inmeye karar verdim. Şaşırtıcı bir şekilde, cevap çok basit:
Kullanmak için geçerli bir neden yoktur (neredeyse *) Uri.EscapeUriString. Bir dizeyi yüzde olarak kodlamanız gerekiyorsa daima kullanın Uri.EscapeDataString.
* Geçerli bir kullanım durumu için son paragrafa bakınız.
Bu neden? Belgelere göre :
Uri yapıcısına parametre olarak çıkış karakteri olmayan bir URI dizesi hazırlamak için EscapeUriString yöntemini kullanın.
Bu gerçekten mantıklı değil. RFC 2396'ya göre :
Bir URI her zaman "kaçar" biçimindedir, çünkü tamamlanmış bir URI'den kaçmak veya kaçmak anlambilimini değiştirebilir.
Alıntılanan RFC, RFC 3986 tarafından kullanılmazken , nokta hala duruyor. Bazı somut örneklere bakarak bunu doğrulayalım:
Bunun gibi basit bir URI'nız var:
http://example.org/
Uri.EscapeUriString değişmeyecek.
Sorgu dizesini kaçmaya dikkat etmeden el ile düzenlemeye karar verdiniz:
http://example.org/?key=two words
Uri.EscapeUriString (doğru) sizin için alandan kaçacak:
http://example.org/?key=two%20wordsSorgu dizesini manuel olarak daha da düzenlemeye karar verdiniz:
http://example.org/?parameter=father&son
Ancak, bu dize değişmez Uri.EscapeUriString, çünkü işareti ve başka bir anahtar / değer çiftinin başlangıcını belirtir. İstediğiniz gibi olabilir veya olmayabilir.
Aslında keyparametrenin olmasını istediğinize siz karar verirsiniz father&son, böylece önceki URL'yi "ve" işaretinden kaçarak manuel olarak düzeltirsiniz:
http://example.org/?parameter=father%26son
Ancak, Uri.EscapeUriStringyüzde karakterinden de kaçarak çift kodlamaya yol açar:
http://example.org/?parameter=father%2526sonGördüğünüz gibi Uri.EscapeUriString, amacına uygun olarak kullanmak &, bir sorgu dizesinde birden çok anahtar / değer çifti arasında ayırıcı yerine bir anahtarın veya değerin bir parçası olarak kullanılmasını imkansız hale getirir .
Bunun nedeni, tam URI'lerden kaçmak için uygun hale getirme girişiminde, ayrılmış karakterleri yok sayar ve yalnızca ne ayrılmış ne de kaydedilmemiş karakterlerden kaçar; BTW, belgelere aykırıdır . Bu şekilde http%3A%2F%2Fexample.org%2F, bunun gibi bir şeyle sonuçlanmazsınız , ancak yukarıda gösterilen sorunlarla sonuçlanırsınız.
Sonunda, URI'niz geçerliyse, Uri yapıcısına bir parametre olarak geçirilmek için kaçmasına gerek yoktur ve geçerli Uri.EscapeUriStringdeğilse, arama da sihirli bir çözüm değildir. Aslında, çoğu durumda olmasa da birçok durumda çalışacaktır, ancak hiçbir şekilde güvenilir değildir.
URL'lerinizi ve sorgu dizelerinizi her zaman anahtar / değer çiftlerini ve yüzde kodlamasını toplayıp ardından gerekli ayırıcılarla birleştirerek oluşturmalısınız. Uri.EscapeDataStringBu amaçla kullanabilirsiniz , ancak kullanamazsınız Uri.EscapeUriString, çünkü yukarıda belirtildiği gibi ayrılmış karakterlerden kaçmaz.
Sadece bunu yapamazsanız, örneğin kullanıcı tarafından sağlanan URI'lerle uğraşırken, Uri.EscapeUriStringson çare olarak kullanmak mantıklıdır . Ancak daha önce belirtilen uyarılar geçerlidir - kullanıcı tarafından sağlanan URI belirsizse, sonuçlar istenmeyebilir.
encodeURI/ Uri.EscapeUriStringolarak gerekli değildir sıklıkta encodeURIComponent/ Uri.EscapeDataString(bir uri bağlamda kullanılması gerekir kör adresler ile deaing olduğunda bu yana), ancak anlamına gelmez onun yeri yok.
Artı (+) karakterler, bu yöntemler arasındaki fark hakkında çok şey ortaya çıkarabilir. Basit bir URI'de, artı karakteri "boşluk" anlamına gelir. Google'ı "mutlu kedi" için sorgulamayı düşünün:
Bu geçerli bir URI (deneyin) ve EscapeUriStringdeğiştirmez.
Şimdi Google'ı "happy c ++" için sorgulamayı düşünün:
Bu geçerli bir URI (deneyin), ancak "mutlu c" için bir arama üretir, çünkü iki artı boşluk olarak yorumlanır. Düzeltmek için, "mutlu c ++" EscapeDataStringve voila * iletebiliriz :
*) Kodlanmış veri dizesi aslında "mutlu% 20c% 2B% 2B" dir; % 20 boşluk karakteri için onaltılı ve% 2B artı karakteri için onaltılı.
Eğer UriBuilderolması gerektiği gibi kullanıyorsanız , sadece EscapeDataStringtüm URI'nizin bazı bileşenlerinden düzgün bir şekilde kaçmanız gerekir . @ Livven'in bu soruya vereceği cevap, kullanmak için gerçekten bir neden olmadığını kanıtlıyor EscapeUriString.
"https://www.google.com/?q=happy c++". Görünüşe göre el ile "?" Üzerine bölmek gerekir, ya da daha iyi bir yolu var mı?
EscapeDataString. Girdiğiniz URL gerçek URL ise, evet sadece ayrılmak istersiniz ?.
Kaynaktaki yorumlar farkı açıkça ele alır. Bu bilgilerin neden XML dokümantasyon yorumları yoluyla sunulmaması benim için bir sırdır.
EscapeUriString:
Bu yöntem, yüzde işaretleri dahil olmak üzere ayrılmış veya kaydedilmemiş bir karakter olmayan herhangi bir karakterden kaçacaktır. EscapeUriString'in '#' işaretinden de kaçmayacağını unutmayın.
EscapeDataString:
Bu yöntem, yüzde işaretleri de dahil olmak üzere, kaydedilmemiş bir karakter olmayan herhangi bir karakterden kaçacaktır.
Fark, ayrılmış karakterleri nasıl ele aldıklarıdır . EscapeDataStringonlardan kaçar; EscapeUriStringdeğil.
RFC'ye göre , ayrılmış karakterler::/?#[]@!$&'()*+,;=
Tamlık için, kaydedilmemiş karakterler alfasayısaldır ve -._~
Her iki yöntem de rezerve edilmemiş veya edilmemiş karakterlerden kaçar.
Ben genel katılmıyorum kavramınaEscapeUriString kötülüktür. Ben sadece yasadışı karakterler (boşluk gibi) kaçan ve ayrılmış değil karakterler bir yöntem yararlı olduğunu düşünüyorum. Ancak %karakteri nasıl ele aldığı konusunda tuhaftır . Yüzde kodlu karakterler ( %ardından 2 onaltılık basamak), bir URI'de yasaldır . EscapeUriStringBu modeli tespit ederse ve %hemen 2 onaltılık basamakla ilerlediğinde kodlamadan kaçınırsa çok daha yararlı olacağını düşünüyorum .
Basit bir örnek
var data = "example.com/abc?DEF=あいう\x20えお";
Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));
/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/
Uri.EscapeDataString()Livven cevabı @ açıklandığı gibi,. Diğer yaklaşımlarla sistem, olası her girdi için amaçlanan sonucu üretmek için yeterli bilgiye sahip değildir.