You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调试AWS示例遇System.Net.ProtocolViolationException请求流内容长度错误

问题描述

运行AWS官网示例代码时触发错误:

System.Net.ProtocolViolationException: 'You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.'

错误出现在CheckResponse方法的这一行:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())

CheckResponse完整代码:

public static void CheckResponse(HttpWebRequest request)
{
    Console.WriteLine("\n-- CHECK RESPONCE");
    // Get the response and read any body into a string, then display.

    Console.WriteLine(request.ContentLength); //857

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        if (response.StatusCode == HttpStatusCode.OK)
        {
            Console.WriteLine("\n-- HTTP call succeeded");
            var responseBody = ReadResponseBody(response);
            if (!string.IsNullOrEmpty(responseBody))
            {
                Console.WriteLine("\n-- Response body:");
                Console.WriteLine(responseBody);                        
            }
        }
        else
            Console.WriteLine("\n-- HTTP call failed, status code: {0}", response.StatusCode);
    }
}

打印request.ContentLength显示为857,但仍报错,手动设置request.ContentLength = 857也无效。调用CheckResponse的InvokeHttpRequest方法代码:

public static void InvokeHttpRequest(Uri endpointUri,
                                     string httpMethod,
                                     IDictionary<string, string> headers,
                                     string requestBody)
{
    try
    {
        var request = ConstructWebRequest(endpointUri, httpMethod, headers);

        if (!string.IsNullOrEmpty(requestBody))
        {
            var buffer = new byte[8192]; // arbitrary buffer size                        
            var requestStream = request.GetRequestStream();
            using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(requestBody)))
            {
                var bytesRead = 0;
                while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    requestStream.Write(buffer, 0, bytesRead);
                }
            }
        }
        CheckResponse(request);
    }
    catch (WebException ex)
    {
        Console.WriteLine(ex.ToString());
        using (var response = ex.Response as HttpWebResponse)
        {
            if (response != null)
            {
                var errorMsg = ReadResponseBody(response);
                Console.WriteLine("\n-- HTTP call failed with exception '{0}', status code '{1}'", errorMsg, response.StatusCode);
            }
        }
    }
}
解决方案

这个错误核心是请求流未被正确关闭/刷新,导致实际写入字节数和ContentLength不匹配(哪怕你看着写够了)。

具体修复步骤:

  1. 妥善处理请求流:把requestStream放进using块,让它自动关闭并释放资源。当前代码里requestStream没被正确处理,写完后流可能还处于未刷新状态,服务器收不到完整字节。

修改InvokeHttpRequest中的请求体写入部分:

if (!string.IsNullOrEmpty(requestBody))
{
    var buffer = new byte[8192];
    // 将requestStream纳入using块,自动关闭
    using (var requestStream = request.GetRequestStream())
    using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(requestBody)))
    {
        int bytesRead;
        while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            requestStream.Write(buffer, 0, bytesRead);
        }
        // 手动刷新流(可选,但更保险)
        requestStream.Flush();
    }
}
  1. 检查ConstructWebRequest方法:确认它是否正确设置了ContentLength。如果该方法已经根据请求体计算并设置了长度,手动赋值会导致冲突;如果没处理,可在获取请求流前,根据请求体的UTF8字节数设置:
byte[] bodyBytes = Encoding.UTF8.GetBytes(requestBody);
request.ContentLength = bodyBytes.Length;

注意必须在GetRequestStream()之前设置ContentLength。

  1. 禁止重复设置ContentLength:如果ConstructWebRequest已经帮你处理了这个值,直接去掉手动设置的代码,避免数值冲突。

为什么打印ContentLength是857还报错?

request.ContentLength只是一个属性值,实际写入流的字节数可能因为流未关闭/刷新,导致服务器没收到完整的857字节,或者流内部计数和该属性不一致。关闭流会强制发送缓冲区字节,同时让HttpWebRequest确认写入字节数和ContentLength匹配。

内容的提问来源于stack exchange,提问作者Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:31:12