使用 HttpClient 时如何在 HttpContent 中设置大字符串?
Posted
技术标签:
【中文标题】使用 HttpClient 时如何在 HttpContent 中设置大字符串?【英文标题】:How to set large string inside HttpContent when using HttpClient? 【发布时间】:2014-05-16 20:05:49 【问题描述】:所以,我创建了一个HttpClient
并使用HttpClient.PostAsync()
发布数据。
我使用
设置HttpContent
HttpContent content = new FormUrlEncodedContent(post_parameters)
;其中post_parameters
是键值对列表List<KeyValuePair<string, string>>
问题是,当HttpContent
的值很大时(转换为base64 的图像要传输)我得到一个URL 太长的错误。这是有道理的——因为网址不能超过 32,000 个字符。但是如果不是这种方式,我该如何将数据添加到HttpContent
?
请帮忙。
【问题讨论】:
我很困惑...当您使用任何类型的HttpContent
(包括FormUrlEncodedContent
)时,数据在正文中而不是在网址中..那么您为什么会在其中看到数据网址?
当我进行以下调用时, dict.Add(new KeyValuePair我在朋友的帮助下想通了。您想要做的是避免使用 FormUrlEncodedContent(),因为它对 uri 的大小有限制。相反,您可以执行以下操作:
var jsonString = JsonConvert.SerializeObject(post_parameters);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
在这里,我们不需要使用 HttpContent 来发布到服务器,StringContent 就完成了!
【讨论】:
> 在这里,我们不需要使用 HttpContent 来发布到服务器,StringContent 完成了工作!StringContent
实际上是HttpContent
(它源自抽象HttpContent
类似于FormUrlEncodedContent
)
这是迄今为止最简单的方法。直到 2016 年初我在这里看到的任何其他东西都是 PITA。
为我工作,感谢您的帮助。【参考方案2】:
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。
【讨论】:
我无法使用此解决方案,因为我使用的是 .Net 4.0,并且无法访问 UrlEncode() 方法。由于工作限制,我无法升级,还有其他想法吗? 通过添加System.Web依赖,可以找到类似的方法HttpUtility.UrlEncode 这个解决方案对我有用。我在使用的 api 中有一些限制,我必须使用“application/x-www-form-urlencoded”来使用它。谢谢。 只是出于兴趣,这里发生了什么? .Replace("%20", "+") 从来没有对堆栈溢出的任何人说过这个。你真是个混蛋!【参考方案3】:这段代码对我有用,基本上你通过http客户端在字符串内容中发送帖子数据“application/x-www-form-urlencoded”,希望这可以帮助像我一样遇到同样问题的人
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();
【讨论】:
但是 OP 的问题是发布大量数据,您没有证明可以通过这种方式完成。但是我看到你在做什么 - 使用application/x-www-form-urlencoded
但绕过使用似乎有内容长度限制的 class FormUrlEncodedContent
。
这基本上对我有用。我改变的是使用WebUtility.UrlEncode("prop2")
而不是HtmlEncode
。我有一个奇怪的 API 端点,需要在表单帖子正文中使用 JSON 数组。有时这个数组可能很大,这就是为什么我需要这样的东西。好东西!以上是关于使用 HttpClient 时如何在 HttpContent 中设置大字符串?的主要内容,如果未能解决你的问题,请参考以下文章
使用 HttpClient.GetAsync() 时如何确定 404 响应状态
使用 System.Net.HttpClient 进行上传时如何跟踪进度? [复制]
在 Java 11 及更高版本中使用 HttpClient 时如何跟踪 HTTP 303 状态代码?