HttpWebRequest иногда неправильно декодирует части параметра запроса

Я заметил кое-что, что кажется отключенным в объекте HttpWebRequest.

Если я запускаю следующее:

var q = "кот (";

(Обратите внимание, что здесь слово "кот" написано на русском языке, по-видимому, оно означает "кот")

 var encoded = Uri.EscapeDataString(q);
 var url = $"https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q={encoded}";

Я получаю следующее значение в URL:

https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=%D0%BA%D0%BE%D1%82%20%28

Если я тогда запустите это:

var r = (HttpWebRequest)WebRequest.Create(url);
r.GetResponse();

В Fiddler вышеупомянутое, по сути, делает запрос:

https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=%D0%BA%D0%BE%D1%82%20(

Обратите внимание, что (не кодируется как%28, как это было, когда я создавал HttpWebRequest.

Если вместо этого я использую:

q = "CAT ("

т.е. без русских символов, только латинский (?), я получаю это как URL:

https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=CAT%20%28

И это тоже просьба, наблюдаемая в Fiddler.

Подводя итог, кажется, что при смешивании латинских и нелатинских символов (кодировка не отправляется.

У кого-нибудь есть предложения, как это решить?

ОБНОВЛЕНИЕ: Это важно, потому что, насколько я могу судить, это причина, по которой я не могу успешно сделать эти запросы API к Twitter, поскольку это, кажется, нарушает нашу подпись OAuth1, мы получаем: HTTP/1.1 401 Авторизация Требуется {"ошибки ":[{"code":32,"message":" Не удалось аутентифицировать вас."}]}

Я даже могу отредактировать ошибочный запрос в Fiddler и заменить его (на%28 в запросе GET, и затем он успешно воспроизведет его с этим единственным изменением.

1 ответ

Это может помочь... похоже, что поведение класса Uri выглядит следующим образом:

var q = "кот (";

var encoded = Uri.EscapeDataString(q);
// encoded = %D0%BA%D0%BE%D1%82%20%28

var uri = new Uri("https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=" + encoded);
// uri.AbsoluteUri = https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=%D0%BA%D0%BE%D1%82%20(

var uri2 = new Uri("https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=CAT (");
// uri2.AbsoluteUri = https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=CAT%20(

var uri3 = new Uri("https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=кот (");
// uri3.AbsoluteUri = https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=true&q=%D0%BA%D0%BE%D1%82%20(

Я не могу отладить в код.NET Framework в настоящее время, но я подозреваю, что использование Uri.EscapeDataString может быть неправильным WRT нелатинские символы и скобки?

Действительно ли работает запрос с незакодированной скобкой? Если это так, я бы предположил, что скобка не нуждается в кодировании...

ОБНОВЛЕНИЕ: я действительно думаю, что это может быть ошибка в Ури?

Другие вопросы по тегам