2012-01-03 6 views
1

Выполнение приведенного ниже кода с помощью Fiddler показывает, что знаки плюс преобразуются в некоторый вид белого пробела. Какую кодировку я должен использовать, чтобы данные не были преобразованы? Я хотел бы держать знаки плюс и т.д.Проблема с кодировкой HttpWebResponse

EDIT: Обновлен пример кода

string postData = "test1=test+plussign&test2=another++twoplussigns"; 
private static byte[] EncodePostData(string postData) 
{ 
    StringBuilder sb = new StringBuilder(); 

    string[] pairs = postData.Split('&'); 
    foreach (string pair in pairs) 
    { 
     string key = Uri.EscapeDataString(pair.Split('=')[0]); 
     string value = Uri.EscapeDataString(pair.Split('=')[1]); 

     sb.AppendFormat("{0}={1}&",key, value); 
    } 
    sb.Remove(sb.Length - 1, 1); 

    return HttpUtility.UrlEncodeToBytes(sb.ToString()); 
} 

А вот метод вызова

byte[] data = EncodePostData(postData); 

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
request.UserAgent = "Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.03"; 
request.CookieContainer = cookies; 
request.Method = "POST"; 
request.ContentType = "application/x-www-form-urlencoded"; 
request.ContentLength = data.Length; 
ServicePointManager.Expect100Continue = false; 

Stream stream = request.GetRequestStream(); 
stream.Write(data, 0, data.Length); 
stream.Close(); 

HttpWebResponse Response = (HttpWebResponse)request.GetResponse(); 
Response.Close(); 
+0

Я обновил этот вопрос, чтобы прояснить немного. – user1231231412

ответ

2

Поскольку переменная называется postData, я буду считать, что вы делаете HTTP POST на веб-сервере.

Wikipedia's summary правил для HTTP POST является:

Когда веб-браузер отправляет запрос POST из веб-формы элемента, тип интернет-СМИ по умолчанию является «применение/х-WWW-форм-urlencoded ». Это формат для кодирования пар ключ-значение с возможно дублирующими ключами . Каждая пара ключей и значений разделяется символом '&', и каждый ключ отделен от его значения символом '='. Ключи и значения обе экранируются путем замены пробелов символом «+», а затем с использованием кодировки URL для всех других не-буквенно-цифровых символов.

То есть, интерпретация по умолчанию '+' в теле HTTP POST является кодированным ' ' характер. Вам необходимо правильно скрыть данные, позвонив по телефону Uri.EscapeDataString или HttpUtility.UrlEncode.

Uri.EscapeDataString("test+PlusSigns"); // returns "test%2BPlusSigns" 

В качестве альтернативы, использовать HttpUtility.UrlEncodeToBytes и записать полученные байты непосредственно в поток запроса (без использования StreamWriter).

(Обратите внимание, что если вы отправляете пар ключ/значение, вам нужно бежать каждый ключ и значение самостоятельно, а затем присоединиться к ним с '=' и '&' символов.)

+0

Спасибо за предложение. Я попробовал и обновил OP, чтобы отразить новый код. Теперь Fiddler показывает, что «данные» получают его = и & закодированы, поэтому вместо отдельных параметров теперь одна большая строка. – user1231231412

+0

Это потому, что вы должны только UrlEncode _values_ (ключ находится перед значением =, значение после этого, каждая пара ключ/значение разделяется амперсандами), а не вся строка POST. – Task

+0

@Jon C: последний вызов 'HttpUtility.UrlEncodeToBytes (sb.ToString())' неверен; это двойное избежание вашего представления. На этом этапе ваша строка уже закодирована по URL-адресу. Так как теперь он должен состоять только из символов ASCII, вы можете использовать 'System.Text.Encoding.ASCII.GetBytes (sb.ToString())', чтобы получить байты для отправки на сервер. –

1

Попробуйте это:

string postData = Uri.EscapeDataString("test+PlusSigns"); 
StreamWriter writer = new StreamWriter(request.GetRequestStream()); 
writer.Write(postData); 
writer.Close(); 

HttpWebResponse Response = (HttpWebResponse)request.GetResponse(); 
Response.Close(); 
+0

Я пробовал это, но ничего не менял. Я также пробовал класс UTF8Encoding. – user1231231412

+0

Я отредактировал свой отзыв – sbtech100

-1

Максимальное значение, которое вы можете сделать, - установить тип содержимого запроса

myReq.ContentType = "text/html; charset=UTF-8"; 
+0

Он спрашивает о данных, которые он задает по запросу, а не о том, что он возвращается. –

+0

О, моя ошибка. – Anand

+0

@AndrewBarber Я обновляю вопрос, чтобы уточнить. То, что я отправляю, именно то, что я хочу, но похоже, что он кодируется HttpWebResponse, когда я рассматриваю его в Fiddler, это неправильно и не совсем то, что я отправил. – user1231231412