2014-05-16 64 views
23

因此,我创建了一个HttpClient,并使用HttpClient.PostAsync()发布数据。如何在使用HttpClient时在HttpContent中设置大字符串?

我设置使用

HttpContent content = new FormUrlEncodedContent(post_parameters)HttpContent;其中post_parameters是键值对List<KeyValuePair<string, string>>

问题是一个列表,当HttpContent有一个较大的值(图像转换为base64要发送的),我得到一个网址太长错误。这是有道理的 - 导致url不能超过32,000个字符。但是,如果不是这样,我如何将数据添加到HttpContent

请帮忙。

+1

Post'StreamContent' –

+0

我很困惑......当你使用任何类型的'HttpContent'(包括'FormUrlEncodedContent')时,数据在主体中,而不在Url ..所以你为什么要在Url中看到数据? –

+0

当我拨打以下电话时, dict.Add(new KeyValuePair (“Base64FileData”,image)); (其中image是base 64转换后的字符串)。抛出异常。 – Muraad

回答

33

我在朋友的帮助下计算出来的。你想要做的就是避免使用FormUrlEncodedContent(),因为它对uri的大小有限制。相反,你可以做到以下几点:

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

在这里,我们并不需要使用HttpContent张贴到服务器,的StringContent干得不错!

+3

>在这里,我们不需要使用HttpContent发布到服务器,StringContent可以完成工作! 'StringContent'实际上是'HttpContent'(它是从类似于'FormUrlEncodedContent'的抽象'HttpContent'派生的) – eXavier

+0

这是迄今为止最简单的方法。我在2016年初看到的其他任何东西都是PITA。 – mafu

23

FormUrlEncodedContent内部使用Uri.EscapeDataString:从反射,我可以看到,这种方法有限制请求长度的常量。

可能的解决方案是通过使用System.Net.WebUtility.UrlEncode(.net 4.5)来绕过此限制创建FormUrlEncodedContent的新实现。

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

+0

我不能使用这个解决方案,因为我使用.Net 4.0,我没有访问方法UrlEncode()。由于工作限制,我无法升级任何其他想法? – Muraad

+0

通过添加一个System.Web依赖项,你可以找到一个类似的方法HttpUtility.UrlEncode – Cybermaxs

+0

你给我的实现和FormUrlEcondedContent()具有相同的限制,但是现在不用抛出异常就可以跳过发送到服务器的调用。 – Muraad

0

此代码对我的作品,基本上你发送POST数据“应用程序/ x-WWW的形式,进行了urlencoded”字符串内容over 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(); 
    } 
+0

但是OP的问题是发布大量的数据,你没有证明可以用这种方式完成。然而,我看到你在做什么 - 使用'application/x-www-form-urlencoded',但绕过使用'类FormUrlEncodedContent'似乎有内容长度限制。 – HankCa

相关问题