C # HttpWebRequest типа «application/x-www-form-urlencoded» — как отправить символ «

#c# #post #httpwebrequest

#c# #Публикация #httpwebrequest

Вопрос:

Я пишу небольшое приложение, подключенное к 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 = "amp;uploadfile=trueamp;file="   iCalStr;

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

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

Если у меня есть ‘amp;nbsp’ где-нибудь в моем календаре (или аналогичном), сервер получает все данные только до точки ‘amp;’, поэтому я предполагаю, что ‘amp;’ делает вид, что все, что после этой точки, принадлежит новому параметру?

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

Комментарии:

1. Закодировать строку перед ее отправкой?

Ответ №1:

Сначала установите «Microsoft ASP.NET Клиент веб-API» пакет 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).Resu<
  

Комментарии:

1. Не уверен, что я чего-то не хватает, но таким образом запрос зависает

2. Что такое OAuth2PostData ?

3. @Kiquenet — Когда вы отправляете запрос с помощью Content-Type of application/x-www-form-urlencoded , обычно требуются некоторые данные. Я скопировал пример кода из кода, который был написан для аутентификации OAuth2, поэтому имя переменной является OAuth2PostData . Имя не важно, это просто переменная, которая содержит данные. По сути, это список KeyValuePair<string, string> .

4. Извините, но как использовать TokenResponse класс? Добавить using Microsoft.Bot.Schema; ?

5. @PhamX. Bach — TokenResponse это ваша модель. Определите класс, который соответствует схеме возврата веб-API, который вы вызываете. Это простой POCO.

Ответ №2:

Поскольку ваш тип контента — application/x-www-form-urlencoded вам нужно будет закодировать текст сообщения, особенно если он содержит символы типа amp; , которые имеют особое значение в форме.

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

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

Комментарии:

1. Вторая ссылка ведет на какой-то японский сайт!

2. Спасибо! Для меня мне просто нужно было преобразовать мою строку strCallString = System.Web.HttpUtility. UrlEncode (strCallString) перед отправкой с помощью . ContentType = «приложение/x-www-form-urlencoded»

Ответ №3:

До тех пор, пока сервер разрешает размещать символ ампрес и (не все делают, поскольку это может быть небезопасно), все, что вам нужно сделать, это кодировать символ по URL. В случае с ampresand вам следует заменить символ на & .

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

 string strNew = "amp;uploadfile=trueamp;file="   HttpUtility.UrlEncode(iCalStr);