错误(HttpWebRequest):要写入流的字节数超过指定的Content-Length字节大小

Vig*_*igs 11 c# byte httpwebrequest httpwebresponse winforms

我似乎无法弄清楚为什么我一直收到以下错误:

Bytes to be written to the stream exceed the Content-Length bytes size specified.
Run Code Online (Sandbox Code Playgroud)

在以下行:

writeStream.Write(bytes, 0, bytes.Length);
Run Code Online (Sandbox Code Playgroud)

这是在Windows窗体项目上.如果有人知道这里发生了什么,我肯定欠你一个.

    private void Post()
    {


        HttpWebRequest request = null;
        Uri uri = new Uri("xxxxx");
        request = (HttpWebRequest)WebRequest.Create(uri);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        XmlDocument doc = new XmlDocument();
        doc.Load("XMLFile1.xml");
        request.ContentLength = doc.InnerXml.Length;
        using (Stream writeStream = request.GetRequestStream())
        {
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] bytes = encoding.GetBytes(doc.InnerXml);
            writeStream.Write(bytes, 0, bytes.Length);
        }
        string result = string.Empty;

        request.ProtocolVersion = System.Net.HttpVersion.Version11;
        request.KeepAlive = false;
        try
        {
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (System.IO.StreamReader readStream = new System.IO.StreamReader(responseStream, Encoding.UTF8))
                    {
                        result = readStream.ReadToEnd();
                    }
                }
            }
        }
        catch (Exception exp)
        {
            // MessageBox.Show(exp.Message);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Lak*_*eld 15

有三种可能的选择

  • 修复ContentLength,如@rene答案所述

  • 不要设置ContentLength,HttpWebRequest正在缓冲数据,并自动设置ContentLength

  • 将SendChunked属性设置为true,并且不设置ContentLength.该请求被发送块编码到Web服务器.(需要HTTP 1.1并且必须得到网络服务器的支持)

码:

...
request.SendChunked = true;
using (Stream writeStream = request.GetRequestStream())
{ ... }
Run Code Online (Sandbox Code Playgroud)


ren*_*ene 10

您的InnerXml中的编码字节数组可能会更长,因为UTF8编码中的某些字符占用单个字符的2或3个字节.

更改您的代码如下:

    using (Stream writeStream = request.GetRequestStream())
    {
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] bytes = encoding.GetBytes(doc.InnerXml);
        request.ContentLength = bytes.Length;
        writeStream.Write(bytes, 0, bytes.Length);
    }
Run Code Online (Sandbox Code Playgroud)

要准确显示正在发生的事情,请在LINQPad中尝试:

var s = "é";
s.Length.Dump("string length");
Encoding.UTF8.GetBytes(s).Length.Dump("array length");
Run Code Online (Sandbox Code Playgroud)

这将输出:

 string length: 1 
 array length:  2 
Run Code Online (Sandbox Code Playgroud)

现在使用e没有撇号的:

var s = "e";
s.Length.Dump("string length");
Encoding.UTF8.GetBytes(s).Length.Dump("array length");
Run Code Online (Sandbox Code Playgroud)

这将输出:

string length: 1 
array length:  1 
Run Code Online (Sandbox Code Playgroud)

请记住:字符串长度和特定编码所需的字节数可能不同.