Domanda

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:\Users\james.billings\Documents\Visual Studio 2012\Projects\PhoneMonitor\PhoneMonitor\GoodData\DataRetriever.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!

È stato utile?

Soluzione 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.

Altri suggerimenti

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

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top