9

我做了一些搜索,大多数人在发送大量数据时似乎都会遇到这个问题,但我不是。

我正在使用以下内容向 API 发出请求:

request.Method = "POST";
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers.Add("Cookie", "$Version=0; GDCAuthTT=" + TToken + "; $Path=/gdc/account");

//generate request parameters
ReportRequest.RootObject reportRequest = new ReportRequest.RootObject();
reportRequest.report_req = new ReportRequest.ReportReq();
reportRequest.report_req.reportDefinition = ReportLink;
JavaScriptSerializer serializer = new JavaScriptSerializer();
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(serializer.Serialize(reportRequest));
request.ContentLength = byteArray.Length;

using (var writer = new System.IO.StreamWriter(request.GetRequestStream(), Encoding.UTF8, byteArray.Length))
{
    writer.Write(byteArray);
}

异常发生在最后一个右括号上:

在写入所有字节之前无法关闭流。说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.IO.IOException:在写入所有字节之前无法关闭流。

源错误:

第 176 行:{ 第 177 行:
writer.Write(byteArray); 第 178 行:} 第 179 行:
字符串响应内容;第 180 行:使用 (var response = request.GetResponse() as System.Net.HttpWebResponse)

源文件:c:\Users\james.billings\Documents\Visual Studio 2012\Projects\PhoneMonitor\PhoneMonitor\GoodData\DataRetriever.cs
行:178

堆栈跟踪:

[IOException: 在写入所有字节之前无法关闭流。]
System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting) +604

[WebException: The request was aborted: The request was cancelled.]
System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting) +6443608
System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeState) +37 System .Net.ConnectStream.Dispose(布尔处理)+44

有什么线索吗?具体来说,我正在尝试使用 GoodData API 调用 xtab2/executor3 - 请参阅http://docs.gooddata.apiary.io/

如果我删除“ set ContentLength”,我会收到 400 Bad Request。如果我像之前的 GET 请求一样设置为 0(工作正常),我会收到一个错误,我尝试写入的长度超过了缓冲区的长度,这是有道理的。

有点难过!

4

3 回答 3

42

request.ContentLength = byteArray.Length;在写入请求流之前不要设置。是自动设置的request.ContentLength

于 2016-02-16T20:53:43.237 回答
5

查看了文档 - System.IO.StreamWriter.Write() - 似乎没有写入字节的方法。

唯一匹配签名的方法是 - StreamWriter.Write(Object)。然而,这会调用ToString()对象并写入输出;这不是你想要的。

当您设置输出缓冲区时;流正在等待这个缓冲区被填充。但是,Object.ToString()可能不会填充此缓冲区,因此会出现错误。

使用BinaryWriterBufferedStream或其他支持byte[]书写的。

于 2013-09-26T10:44:39.590 回答
5

对我来说,Json 请求中的特殊字符 (é) 出了问题。出于某种原因,我不得不手动设置 ContentLength。

感谢此页面上的提示,我将代码更改为以下内容,对我来说它现在可以工作了。

旧版:

string content = "{ test: \"olé\" }";

_Request.ContentLength  = content.Length;

using ( var writer = new StreamWriter(_Request.GetRequestStream()) ) 
    writer.Write( content );

新版本:

string content = "{ test: \"olé\" }";

byte[] bytes            = Encoding.UTF8.GetBytes(content);
_Request.ContentLength  = bytes.Length;

using ( var writer = _Request.GetRequestStream() )
    writer.Write(bytes, 0, bytes.Length);
于 2019-07-01T12:19:21.587 回答