web-dev-qa-db-ja.com

HttpClientを使用するときにHttpContent内に大きな文字列を設定する方法は?

そこで、HttpClientを作成し、HttpClient.PostAsync()を使用してデータを投稿しています。

を使用してHttpContentを設定します

HttpContent content = new FormUrlEncodedContent(post_parameters);ここで、post_parametersは、キーと値のペアのリストですList<KeyValuePair<string, string>>

問題は、HttpContentの値が大きい場合(画像がbase64に変換されて送信される)、URLが長すぎるというエラーが発生することです。それは理にかなっています-URLが32,000文字を超えることはできません。しかし、このようにしない場合、どのようにしてHttpContentにデータを追加しますか?

助けてください。

32
Muraad

私は友人の助けを借りてそれを理解しました。 uriのサイズに制限があるため、FormUrlEncodedContent()の使用を避けてください。代わりに、次のことができます。

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

ここでは、HttpContentを使用してサーバーに投稿する必要はありません。StringContentがジョブを完了します!

55
Muraad

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 を使用することをお勧めします。

28
Cybermaxs

このコードは私のために機能します。基本的には、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();
    }
3
Chris