C # HttpWebRequest типа «application / x-www-form-urlencoded» - как отправить символ «&» в теле содержимого? - PullRequest
31 голосов
/ 14 апреля 2011

Я пишу небольшое приложение, связанное с API, на C #.

Я подключаюсь к API, у которого есть метод, который принимает длинную строку, содержимое файла календаря (ics).

Я делаю это так:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
request.Method = "POST";
request.AllowAutoRedirect = false;
request.CookieContainer = my_cookie_container;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.ContentType = "application/x-www-form-urlencoded";

string iCalStr = GetCalendarAsString();

string strNew = "&uploadfile=true&file=" + iCalStr;

using (StreamWriter stOut = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII))
 {
     stOut.Write(strNew);
     stOut.Close();
 }

Кажется, это прекрасно работает, пока я не добавлю какой-то определенный HTML в свой календарь.

Если у меня есть «& nbsp» где-то в моем календаре (или аналогичном), сервер передает все данные только до точки «&», поэтому я предполагаю, что «&» делает это похожим на что-либо после этого точка принадлежит новому параметру?

Как я могу это исправить?

Ответы [ 3 ]

35 голосов
/ 30 июня 2015

Первая установка " Microsoft ASP.NET Web API Client " пакет nuget:

  PM > Install-Package Microsoft.AspNet.WebApi.Client

Затем используйте следующую функцию для публикации ваших данных:

public static async Task<TResult> PostFormUrlEncoded<TResult>(string url, IEnumerable<KeyValuePair<string, string>> postData)
{
    using (var httpClient = new HttpClient())
    {
        using (var content = new FormUrlEncodedContent(postData))
        {
            content.Headers.Clear();
            content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            HttpResponseMessage response = await httpClient.PostAsync(url, content);

            return await response.Content.ReadAsAsync<TResult>();
        }
    }
}

А вот как это использовать:

TokenResponse tokenResponse = 
    await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData);

или

TokenResponse tokenResponse = 
    (Task.Run(async () 
        => await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData)))
        .Result

или (не рекомендуется)

TokenResponse tokenResponse = 
    PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData).Result;
24 голосов
/ 14 апреля 2011

Поскольку ваш тип содержимого - application/x-www-form-urlencoded, вам необходимо кодировать тело POST, особенно если оно содержит символы типа &, которые имеют особое значение в форме.

Попробуйте передать строку через HttpUtility.UrlEncode перед записью в поток запросов.

Вот несколько ссылок для справки.

8 голосов
/ 14 апреля 2011

Пока сервер допускает отправку символа амперсанда (не все делают, как это может быть небезопасно), все, что вам нужно сделать, это кодировать URL-адрес символа.В случае амперсанда вы должны заменить символ на %26.

.NET предоставляет хороший способ кодирования всей строки для вас:

string strNew = "&uploadfile=true&file=" + HttpUtility.UrlEncode(iCalStr);
...