【问题标题】:How to set large string inside HttpContent when using HttpClient?使用 HttpClient 时如何在 HttpContent 中设置大字符串?
【发布时间】: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("Base64FileData", image)); (其中 image 是 base 64 转换后的字符串)。抛出异常。

标签: c# .net asp.net-web-api httpclient httpcontent


【解决方案1】:

我在朋友的帮助下想通了。您想要做的是避免使用 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 数组。有时这个数组可能很大,这就是为什么我需要这样的东西。好东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
相关资源
最近更新 更多