Cannot close stream until all bytes are written (GoodData API)

I’ve done a bit of searching, and most people seem to hit this when sending larger amounts of data, but I’m not.

I’m making a request to an API with the following:

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

The exception occurs on the last closing bracket:

Cannot close stream until all bytes are written. Description: An
unhandled exception occurred during the execution of the current web
request. Please review the stack trace for more information about the
error and where it originated in the code.

Exception Details: System.IO.IOException: Cannot close stream until
all bytes are written.

Source Error:

Line 176: { Line 177:
writer.Write(byteArray); Line 178: } Line 179:
string responseContent; Line 180: using (var response =
request.GetResponse() as System.Net.HttpWebResponse)

Source File: c:Usersjames.billingsDocumentsVisual Studio
2012ProjectsPhoneMonitorPhoneMonitorGoodDataDataRetriever.cs
Line: 178

Stack Trace:
[IOException: Cannot close stream until all bytes are written.]
System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean
aborting) +604
[WebException: The request was aborted: The request was canceled.]
System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean
aborting) +6443608
System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState
closeState) +37 System.Net.ConnectStream.Dispose(Boolean disposing)
+44

Any clues? Specifically I’m trying to use the GoodData API call xtab2/executor3 – see http://docs.gooddata.apiary.io/

If I remove the “set ContentLength” I get a 400 Bad Request. If I set to 0 like earlier GET requests (which work fine) I get an error that I tried to write more than the length of the buffer, which makes sense.

Bit stumped!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Do not set request.ContentLength = byteArray.Length; before writing the request stream. The request.ContentLength is set automatically.

Method 2

For me it was going wrong with a special character (é) in a Json request. For some reason I had to set the ContentLength manually.

Thanks to the tip on this page I changed my code to the following and for me it works now.

Old version:

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

_Request.ContentLength  = content.Length;

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

New version:

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

Method 3

Having looked over the docs – System.IO.StreamWriter.Write() – There does not appear to be a method for writing bytes.

The only method that matches the signature is – StreamWriter.Write(Object). This however calls ToString() on the object and writes the output; Which is not what you want.

As you are setting an output buffer; the stream is waiting for this buffer to be filled. However, the Object.ToString() will likely not fill this buffer and hence the error.

Use BinaryWriter, BufferedStream or another that supports byte[] writing.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x