C# 使用HttpClient时,如何在HttpContent中设置大字符串?

C# 使用HttpClient时,如何在HttpContent中设置大字符串?,c#,.net,asp.net-web-api,httpclient,httpcontent,C#,.net,Asp.net Web Api,Httpclient,Httpcontent,因此,我创建了一个HttpClient,并使用HttpClient.PostAsync()发布数据 我使用 HttpContent content=newformurlencodedcontent(post_参数);其中post_参数是键值对的列表list 问题是,当HttpContent有一个大值(一个转换为base64的图像要传输)时,我得到一个URL太长的错误。这是有道理的-因为url不能超过32000个字符。但是如果不是这样,我如何将数据添加到HttpContent 请帮助。FormUr

因此,我创建了一个
HttpClient
,并使用
HttpClient.PostAsync()
发布数据

我使用

HttpContent content=newformurlencodedcontent(post_参数)
;其中
post_参数
是键值对的列表
list

问题是,当
HttpContent
有一个大值(一个转换为base64的图像要传输)时,我得到一个URL太长的错误。这是有道理的-因为url不能超过32000个字符。但是如果不是这样,我如何将数据添加到
HttpContent


请帮助。

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", "+");
    }
}
公共类MyFormUrlEncodedContent:ByteArrayContent
{
公共MyFormUrlEncodedContent(IEnumerable nameValueCollection)
:base(MyFormUrlEncodedContent.GetContentByteArray(nameValueCollection))
{
base.Headers.ContentType=新的MediaTypeHeaderValue(“application/x-www-form-urlencoded”);
}
私有静态字节[]GetContentByteArray(IEnumerable nameValueCollection)
{
如果(nameValueCollection==null)
{
抛出新ArgumentNullException(“nameValueCollection”);
}
StringBuilder StringBuilder=新的StringBuilder();
foreach(nameValueCollection中当前的KeyValuePair)
{
如果(stringBuilder.Length>0)
{
stringBuilder.Append('&');
}
追加(MyFormUrlEncodedContent.Encode(current.Key));
stringBuilder.Append('=');
追加(MyFormUrlEncodedContent.Encode(current.Value));
}
返回Encoding.Default.GetBytes(stringBuilder.ToString());
}
专用静态字符串编码(字符串数据)
{
if(string.IsNullOrEmpty(数据))
{
返回字符串。空;
}
返回System.Net.WebUtility.UrlEncode(数据)。替换(“%20”和“+”);
}
}

要发送大量内容,最好使用。

我在朋友的帮助下找到了答案。您要做的是避免使用FormUrlEncodedContent(),因为它对uri的大小有限制。相反,您可以执行以下操作:

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

在这里,我们不需要使用HttpContent发布到服务器,StringContent完成了任务

这段代码适合我,基本上你可以通过http客户端发送字符串内容中的post数据“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();
    }

我很困惑…当您使用任何类型的
HttpContent
(包括
FormUrlEncodedContent
)时,数据都在正文中,而不是在Url中。那么您为什么要在Url中看到数据呢?当我进行以下调用时,dict.Add(new KeyValuePair(“Base64FileData”,image));(其中image是基64转换字符串)。引发异常。我无法使用此解决方案,因为我使用的是.Net 4.0,并且我无权访问方法UrlEncode()。由于工作限制,我无法升级,还有其他想法吗?通过添加System.Web依赖项,您可以找到类似的方法HttpUtility.urlencode此解决方案对我有效。我在使用的api中有一些限制,我必须使用“application/x-www-form-urlencoded”来使用这些限制。谢谢。只是出于兴趣,这里发生了什么事。Replace(“%20”和“+”)从未对堆栈溢出上的任何人说过这句话。你真是个坏蛋!>在这里,我们不需要使用HttpContent发布到服务器,StringContent完成了任务
StringContent
实际上是
HttpContent
(它源自抽象
HttpContent
,类似于
FormUrlEncodedContent
),这是迄今为止最简单的方法。截至2016年初,我在这里看到的任何其他内容都是PITA。感谢您的帮助,这对我很有用。但OPs的问题是发布了大量数据,您还没有证明可以通过这种方式完成。但是我看到了您正在做的事情-使用
application/x-www-form-urlencoded
,但绕过了
class-FormUrlEncodedContent
,它似乎有内容长度限制。这基本上对我有效。我改变的是使用
WebUtility.UrlEncode(“prop2”)
而不是
HtmlEncode
。我有一个奇怪的API端点,它要求在表单post主体中包含一个JSON数组。有时,这个阵列可能是巨大的,这就是为什么我需要这样的东西。好东西!