【问题标题】:HttpRequest and POSTHttpRequest 和 POST
【发布时间】:2011-08-30 06:00:29
【问题描述】:

我不断收到以下错误消息之一:

"The remote server returned an error: (400) Bad Request."  
               OR
"System.Net.ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse."

这是我正在运行的代码:

        StringBuilder bld = new StringBuilder();
        bld.Append("contractId=");
        bld.Append(ctrId);
        bld.Append("&companyIds=");
        bld.Append("'" + company1+ ", " + company2+ "'");

        HttpWebRequest req = (HttpWebRequest)WebRequest
            .Create(secureServiceUrl + "SetContractCompanyLinks");
        req.Credentials = service.Credentials;
        //req.AllowWriteStreamBuffering = true;
        req.Method = "POST";
        req.ContentType = "application/x-www-form-urlencoded";
        req.ContentLength = bld.Length;
        StreamWriter writer = new StreamWriter(req.GetRequestStream());
        var encodedData = Encoding.ASCII.GetBytes(bld.ToString());
        writer.Write(encodedData);
        writer.Flush();
        writer.Close();
        var resp = req.GetResponse();

【问题讨论】:

  • 您的请求中一定有问题/缺失。您检查过应用程序日志是否有错误?
  • 是的,我检查了它,但没有出现任何内容,可能是我没有配置好。我再检查一下。
  • 这可能不是 400 响应的原因,但您应该 URLEncode ctrId"'" + company1+ ", " + company2+ "'"
  • 现在我遇到了异常:System.Net.ProtocolViolationException: 您必须在调用 [Begin]GetResponse 之前将 ContentLength 字节写入请求流。

标签: c# .net wcf


【解决方案1】:

一些“关闭”的事情:

直接写给你的作家 没有理由调用 GetBytes()。 StreamWriter 完全能够将字符串写入流:

writer.Write(bld.ToString());

在 StreamWriter 周围使用 using() {} 模式

这将确保正确处置 writer 对象。

using(var writer = new StreamWriter(req.GetRequestStream()))
{
   writer.Write(bld.ToString());
}

您无需明确设置内容长度 不用管它,框架会根据您写入请求流的内容为您设置它。

如果您需要明确使用 ASCII,请在 Content-Type 标头中设置字符集

req.ContentType = "application/x-www-form-urlencoded; charset=ASCII";

您还应该在实例化 StreamWriter 时指定编码:

new StreamWriter(req.GetRequestStream(), Encoding.ASCII)

【讨论】:

  • 更正代码后,我仍然收到一个错误的请求异常,说明查询语法有错误
  • 您能找到 fiddler (fiddler2.com/fiddler2) 并将您请求的原始内容发布到您的问题吗?
【解决方案2】:
    req.ContentLength = bld.Length;
    StreamWriter writer = new StreamWriter(req.GetRequestStream());
    var encodedData = Encoding.ASCII.GetBytes(bld.ToString());
    writer.Write(encodedData);

你写的不是你说你要写的东西——你写的是ASCII编码的字节而不是你原来的字节数组——ContentLength必须与你写的字节数相匹配。而是这样做:

    var encodedData = Encoding.ASCII.GetBytes(bld.ToString());
    req.ContentLength = encodedData.Length;

【讨论】:

  • 我确信这是一个很好的建议,但是,请注意,我来到这里时遇到了与 OP 相同的错误,但我的代码确实完全按照这个答案的建议,即采用了编码字节的长度并将其设置在 ContentLength - 但我仍然得到“您必须在调用 [Begin]GetResponse 之前将 ContentLength 字节写入请求流”。不过,它是间歇性的......在数百名用户每天多次调用相同的代码而没有遇到任何问题之后,我曾经遇到过这个错误。
猜你喜欢
  • 2016-04-20
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
相关资源
最近更新 更多