在写入所有字节之前无法关闭流(GoodData API)

时间:2013-09-26 10:33:42

标签: c# asp.net .net gooddata

我已经做了一些搜索,大多数人似乎在发送大量数据时遇到这种情况,但我不是。

我正在向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(字节阵列);第178行:}第179行:
  string responseContent;第180行:使用(var response =   request.GetResponse()as System.Net.HttpWebResponse)

     

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

     

堆栈追踪:

     

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

     

[WebException:请求已中止:请求已取消。]
  System.Net.ConnectStream.CloseInternal(Boolean internalCall,Boolean   中止)+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错误请求。如果我像早期的GET请求一样设置为0(工作正常)我得到一个错误,我试图写入超过缓冲区的长度,这是有道理的。

有点难过!

3 个答案:

答案 0 :(得分:31)

在写入请求流之前,请勿设置request.ContentLength = byteArray.Length;request.ContentLength会自动设置。

答案 1 :(得分:4)

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

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

在设置输出缓冲区时;流正在等待填充此缓冲区。但是,Object.ToString()可能不会填充此缓冲区,从而导致错误。

使用BinaryWriterBufferedStream或其他支持byte[]写作的内容。

答案 2 :(得分:1)

对我来说,在Json请求中使用特殊字符(é)出错。由于某些原因,我必须手动设置ContentLength。

感谢this page的提示,我将代码更改为以下代码,对我来说现在可以使用了。

旧版本:

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);