Как установить большую строку внутри HttpContent при использовании HttpClient?
Итак, я создал HttpClient
и публикую данные с помощью HttpClient.PostAsync()
.
я поставил HttpContent
используя
HttpContent content = new FormUrlEncodedContent(post_parameters)
; где post_parameters
список пар значений ключей List<KeyValuePair<string, string>>
проблема в том, когда HttpContent
имеет большое значение (изображение, преобразованное в base64 для передачи) я получаю URL-адрес слишком длинной ошибки. Это имеет смысл-потому что url-адрес не может превышать 32 000 символов. Но как добавить данные в HttpContent
если не так?
пожалуйста помощь.
3 ответов
Я понял это с помощью моего друга. Что вы хотели бы сделать, это избежать использования FormUrlEncodedContent (), потому что он имеет ограничения на размер uri. Вместо этого, вы можете сделать следующее :
var jsonString = JsonConvert.SerializeObject(post_parameters);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
здесь нам не нужно использовать HttpContent для публикации на сервере, StringContent выполняет работу !
FormUrlEncodedContent
внутренне использует Uri.EscapeDataString
: из отражения я вижу, что этот метод имеет константы, ограничивающие размер длины запроса.
возможным решением является создание новой реализации FormUrlEncodedContent
С помощью System.Net.WebUtility.UrlEncode
(.нетто 4.5), чтобы обойти это ограничение.
public class MyFormUrlEncodedContent : ByteArrayContent
{
public MyFormUrlEncodedContent(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
: base(MyFormUrlEncodedContent.GetContentByteArray(nameValueCollection))
{
base.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
}
private static byte[] GetContentByteArray(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
{
if (nameValueCollection == null)
{
throw new ArgumentNullException("nameValueCollection");
}
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, string> current in nameValueCollection)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append('&');
}
stringBuilder.Append(MyFormUrlEncodedContent.Encode(current.Key));
stringBuilder.Append('=');
stringBuilder.Append(MyFormUrlEncodedContent.Encode(current.Value));
}
return Encoding.Default.GetBytes(stringBuilder.ToString());
}
private static string Encode(string data)
{
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
return System.Net.WebUtility.UrlEncode(data).Replace("%20", "+");
}
}
чтобы отправить большой контент, лучше использовать StreamContent.
этот код работает для меня, в основном вы отправляете данные post "application / x-www-form-urlencoded" в строковом содержимом через http-клиент, надеюсь, это может помочь любому с той же проблемой, как я
void sendDocument()
{
string url = "www.mysite.com/page.php";
StringBuilder postData = new StringBuilder();
postData.Append(String.Format("{0}={1}&", HttpUtility.HtmlEncode("prop"), HttpUtility.HtmlEncode("value")));
postData.Append(String.Format("{0}={1}", HttpUtility.HtmlEncode("prop2"), HttpUtility.HtmlEncode("value2")));
StringContent myStringContent = new StringContent(postData.ToString(), Encoding.UTF8, "application/x-www-form-urlencoded");
HttpClient client = new HttpClient();
HttpResponseMessage message = client.PostAsync(url, myStringContent).GetAwaiter().GetResult();
string responseContent = message.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}