TL; DR: स्वीकार किए गए संस्करण का उपयोग न करें क्योंकि यह यूनिकोड वर्णों को संभालने के संबंध में पूरी तरह से टूट गया है, और कभी भी आंतरिक API का उपयोग नहीं करता है
मुझे वास्तव में स्वीकृत समाधान के साथ अजीब डबल एन्कोडिंग मुद्दा मिला है:
इसलिए, यदि आप उन वर्णों के साथ काम कर रहे हैं जिन्हें एन्कोडेड करने की आवश्यकता है, तो स्वीकृत समाधान दोहरे एन्कोडिंग की ओर जाता है:
NameValueCollection
इंडेक्सर का उपयोग करके क्वेरी पैरामीटर ऑटो एनकोडेड हैं ( और यह उपयोग करता है UrlEncodeUnicode
, नियमित रूप से अपेक्षित नहीं UrlEncode
! ( )
- फिर, जब आप कॉल करते हैं तो
uriBuilder.Uri
यह नया Uri
प्रयोग करता है कंस्ट्रक्टर जो एक बार (सामान्य यूआरएल एन्कोडिंग) एन्कोडिंग करता है
- ऐसा करने से बचा नहीं जा सकता है
uriBuilder.ToString()
(भले ही यह सही हो Uri
जो IMO कम से कम असंगति है, शायद एक बग है, लेकिन यह एक और सवाल है) और फिर HttpClient
स्ट्रिंग को स्वीकार करने की विधि का उपयोग करना - क्लाइंट अभी भी Uri
इस तरह से आपके पास किए गए स्ट्रिंग से बाहर निकलता है:new Uri(uri, UriKind.RelativeOrAbsolute)
छोटा, लेकिन पूर्ण रेपो:
var builder = new UriBuilder
{
Scheme = Uri.UriSchemeHttps,
Port = -1,
Host = "127.0.0.1",
Path = "app"
};
NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
query["cyrillic"] = "кирилиця";
builder.Query = query.ToString();
Console.WriteLine(builder.Query); //query with cyrillic stuff UrlEncodedUnicode, and that's not what you want
var uri = builder.Uri; // creates new Uri using constructor which does encode and messes cyrillic parameter even more
Console.WriteLine(uri);
// this is still wrong:
var stringUri = builder.ToString(); // returns more 'correct' (still `UrlEncodedUnicode`, but at least once, not twice)
new HttpClient().GetStringAsync(stringUri); // this creates Uri object out of 'stringUri' so we still end up sending double encoded cyrillic text to server. Ouch!
आउटपुट:
?cyrillic=%u043a%u0438%u0440%u0438%u043b%u0438%u0446%u044f
https://127.0.0.1/app?cyrillic=%25u043a%25u0438%25u0440%25u0438%25u043b%25u0438%25u0446%25u044f
जैसा कि आप देख सकते हैं, अगर आप कोई फर्क नहीं पड़ता uribuilder.ToString()
+ httpClient.GetStringAsync(string)
या uriBuilder.Uri
+ httpClient.GetStringAsync(Uri)
आप डबल एन्कोडेड पैरामीटर भेज अंत
निश्चित उदाहरण हो सकता है:
var uri = new Uri(builder.ToString(), dontEscape: true);
new HttpClient().GetStringAsync(uri);
लेकिन यह अप्रचलित Uri
कंस्ट्रक्टर का उपयोग करता है
Windows सर्वर पर मेरे नवीनतम .NET पर PS, Uri
बूल डॉक टिप्पणी के साथ कंस्ट्रक्टर "अप्रचलित, NOTEscape हमेशा गलत है", लेकिन वास्तव में अपेक्षित रूप से काम करता है (स्किप्स एस्केपिंग)
तो यह एक और बग की तरह लग रहा है ...
और यहां तक कि यह सामान्य गलत है - यह सर्वर को UrlEncodedUnicode भेजता है, न कि केवल UrlEncoded सर्वर को इसकी अनुमति देता है
अद्यतन: एक और बात है, NameValueCollection वास्तव में UrlEncodeUnicode करता है, जिसे अब उपयोग नहीं किया जाना है और नियमित url.encode / decode ( URL Query के लिए NameValueCollection देखें ) के साथ असंगत है ।
इसलिए नीचे की रेखा है: इस हैक का उपयोग कभी न करेंNameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
क्योंकि यह आपके यूनिकोड क्वेरी मापदंडों को गड़बड़ कर देगा। बस मैन्युअल रूप से क्वेरी बनाएं और इसे असाइन करें UriBuilder.Query
जो आवश्यक एन्कोडिंग करेगा और फिर उरी का उपयोग कर प्राप्त करेगा UriBuilder.Uri
।
कोड का उपयोग करके खुद को चोट पहुंचाने का प्रमुख उदाहरण जो इस तरह का उपयोग करने वाला नहीं है