2014-05-16 17 views
23

Stworzyłem więc HttpClient i przesyłam dane, używając HttpClient.PostAsync().Jak ustawić duży ciąg wewnątrz HttpContent podczas korzystania z HttpClient?

ustawić HttpContent korzystając

HttpContent content = new FormUrlEncodedContent(post_parameters); gdzie post_parameters to lista par wartości klucza List<KeyValuePair<string, string>>

Problem jest, gdy HttpContent ma dużą wartość (obraz konwertowany do base64 być transmitowane) uzyskać adres URL jest zbyt długi błąd. To ma sens - ponieważ URL nie może przekroczyć 32 000 znaków. Ale jak mogę dodać dane do HttpContent, jeśli nie w ten sposób?

Proszę o pomoc.

+1

Post 'StreamContent' –

+0

Jestem zdezorientowany ... kiedy używasz jakiegokolwiek' HttpContent' (w tym 'FormUrlEncodedContent') dane są w treści, a nie w Url ... tak, dlaczego widzisz dane w Url? –

+0

Kiedy wykonuję następujące połączenie, dict.Add (new KeyValuePair ("Base64FileData", obraz)); (gdzie obraz jest podstawowym 64 skonwertowanym łańcuchem). Wyjątek został zgłoszony. – Muraad

Odpowiedz

33

Wyjaśniałem to z pomocą przyjaciela. To, co chciałbyś zrobić, to unikać użycia FormUrlEncodedContent(), ponieważ ma ona ograniczenia dotyczące rozmiaru URI. Zamiast tego, można wykonać następujące czynności:

var jsonString = JsonConvert.SerializeObject(post_parameters); 
    var content = new StringContent(jsonString, Encoding.UTF8, "application/json"); 

Tutaj nie musimy używać HttpContent aby umieścić na serwerze, StringContent dostaje zadanie!

+3

> Tutaj nie musimy używać HttpContent do publikowania na serwerze, StringContent dostaje zadanie! 'StringContent' faktycznie jest' HttpContent' (pochodzi od abstrakcyjnego 'HttpContent' podobnie jak' FormUrlEncodedContent') – eXavier

+0

Jest to zdecydowanie najłatwiejszy sposób. Wszystko, co widziałem tutaj do początku 2016 roku, to PITA. – mafu

23

FormUrlEncodedContent używa wewnętrznie : od odbicia, widzę, że ta metoda ma stałe ograniczające rozmiar długości żądania. Możliwe jest utworzenie nowej implementacji FormUrlEncodedContent przy użyciu System.Net.WebUtility.UrlEncode (.net 4.5) w celu ominięcia tego ograniczenia.

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", "+"); 
    } 
} 

Aby wysłać dużą zawartość, lepiej użyć numeru StreamContent.

+0

Nie mogę użyć tego rozwiązania, ponieważ używam .Net 4.0 i nie mam dostępu do metody UrlEncode(). Nie mogę dokonać aktualizacji z powodu ograniczeń pracy, żadnych innych myśli? – Muraad

+0

, dodając zależność System.Web, można znaleźć podobną metodę HttpUtility.UrlEncode – Cybermaxs

+0

implementacja, którą mi dałeś, ma te same ograniczenia co FormUrlEcondedContent(), ale teraz zamiast rzucać wyjątek, pomija połączenie, aby publikować na serwerze. – Muraad

0

Ten kod działa dla mnie, w zasadzie wysyłania danych post „application/x-www-form-urlencoded” w treści strun nad klientem HTTP nadzieję, że może pomóc każdemu z tym samym problemem jak ja

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(); 
    } 
+0

Jednak problem z OP polegał na publikowaniu dużych ilości danych, których nie udowodniono w ten sposób. Jednak widzę, co robisz - używając 'application/x-www-form-urlencoded' ale omijając używając' class FormUrlEncodedContent ', która wydaje się mieć ograniczenie długości treści. – HankCa

Powiązane problemy