Yanıtlar:
EscapeDataString
Her 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%20words
Sorgu 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 key
parametrenin 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.EscapeUriString
yüzde karakterinden de kaçarak çift kodlamaya yol açar:
http://example.org/?parameter=father%2526son
Gö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.EscapeUriString
değ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.EscapeDataString
Bu 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.EscapeUriString
son ç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.EscapeUriString
olarak 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 EscapeUriString
değ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 ++" EscapeDataString
ve 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 UriBuilder
olması gerektiği gibi kullanıyorsanız , sadece EscapeDataString
tü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 . EscapeDataString
onlardan kaçar; EscapeUriString
değ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 . EscapeUriString
Bu 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.