HttpWebRequest не отправляет символ + (плюс) - PullRequest
3 голосов
/ 25 июля 2011

Я пытаюсь отправить данные в кодировке base64 с помощью запроса POST, и он содержит символ "+". Когда я отправляю запрос, «+» заменяется на «» (пробел). Здесь идет код

    public string POST(string url, string query)
    {
        HttpWebRequest hwrq = CreateRequest(url);
        hwrq.CookieContainer = Cookies;
        hwrq.Method = "POST";
        hwrq.ContentType = "application/x-www-form-urlencoded";
        byte[] data = Encoding.Default.GetBytes(query);
        hwrq.ContentLength = data.Length;
        hwrq.GetRequestStream().Write(data, 0, data.Length);
        using (HttpWebResponse hwrs = (HttpWebResponse)hwrq.GetResponse())
        {
            using (StreamReader sr = new StreamReader(hwrs.GetResponseStream()))
            {
                return sr.ReadToEnd().Trim();
            }
        }
    }

    public HttpWebRequest CreateRequest(string url)
    {
        HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(url);
        Request.UserAgent = UserAgent;
        Request.Accept = Accept;
        Request.Headers.Add("Accept-Language", AcceptLang);
        Request.AutomaticDecompression = DMethod;
        return Request;
    }

Я отслеживал переменную «query», она остается с символом «+», но когда я вижу запрос в сниффере (Charles), запрос отправляется без «+». Например я пытаюсь отправить

<...> zxJ + zZq <...>

и

<...> zxJ zZq <...>

фактически отправлено.
Что я делаю не так?
Заранее спасибо.

Ответы [ 3 ]

10 голосов
/ 25 июля 2011

+ представляет пробел в строке запроса. Похоже, что отправляемая вами переменная query неправильно закодирована в URL. К сожалению, вы не показали, как вы строите эту query строковую переменную, но вот правильный путь для обеспечения того, чтобы все значения были правильно закодированы URL:

var values = HttpUtility.ParseQueryString(string.Empty);
values["foo"] = "some + value";
values["bar"] = "some other value";
string query = values.ToString();
// query will equal foo=some+%2b+value&bar=some+other+value

Обратите внимание, как знак +, который изначально был частью значения, закодирован в %2B.

Если вы напишите следующее:

string query = "foo=some + value&bar=some other value";

Я думаю, вы видите проблему для себя и разницу между правильной строкой запроса, которая foo=some+%2b+value&bar=some+other+value.

Теперь, как говорится, вот что я бы предложил вам, чтобы улучшить ваш код. Вы можете расширить класс WebClient, чтобы он мог обрабатывать файлы cookie, например:

public class WebClientEx : WebClient
{
    public CookieContainer Cookies { get; private set; }
    public WebClientEx()
    {
        Cookies = new CookieContainer();
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = (HttpWebRequest)base.GetWebRequest(address);
        request.CookieContainer = Cookies;
        return request;
    }
}

а теперь просто:

using (var client = new WebClientEx())
{
    client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0";
    client.Headers[HttpRequestHeader.AcceptLanguage] = "en-us,en;q=0.5";
    var values = new NameValueCollection
    {
        { "foo", "some value" },
        { "bar", "some & other + value =" },
    };
    byte[] buffer = client.UploadValues("http://www.example.com", values);
    string result = Encoding.UTF8.GetString(buffer);
}

Посмотрите, насколько это проще, чем возиться со всеми этими запросами HttpWeb, ответами, потоками, кодировками и т. Д.?

1 голос
/ 25 июля 2011

Данные формы отправляются в кодированном URL-адресе, а пробел кодируется в +, поэтому + будет декодирован в пробел.

Используйте метод Server.UrlEncode для кодирования данных, которые вы хотите отправить.

0 голосов
/ 04 сентября 2013

Попробуйте использовать другой тип контента:

hwrq.ContentType = "text/plain";

В вашем примере вы публикуете необработанные данные base64 (простой текст), но сообщаете удаленному серверу, что публикуете строку запроса в кодировке URL (application /х-WWW-форм-urlencoded).Вот почему удаленный сервер пытается url-декодировать ваши данные base64, что, в свою очередь, заменит + пробелом.

...