2013-09-26 1 views
5

Я немного поработал, и большинство людей, похоже, попадают в это при отправке больших объемов данных, но я не знаю.Не удается закрыть поток до тех пор, пока не будут записаны все байты (API 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); 
      } 

за исключением происходит на последней закрывающей скобкой:

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

Любые подсказки? В частности, я пытаюсь использовать API-интерфейс GoodData xtab2/executor3 - см. http://docs.gooddata.apiary.io/

Если я удалю «set ContentLength», я получаю 400 Bad Request. Если я установил значение 0, как раньше, запросы GET (которые работают нормально), я получаю сообщение об ошибке, которое я пытался записать больше, чем длина буфера, что имеет смысл.

Битва в тупике!

ответ

3

Просмотрев документы - System.IO.StreamWriter.Write() - Не существует способа написания байтов.

Единственный способ, который соответствует подписи - StreamWriter.Write(Object). Однако это вызывает ToString() на объект и записывает вывод; Это не то, что вы хотите.

Поскольку вы устанавливаете выходной буфер; поток ожидает заполнения этого буфера. Однако Object.ToString(), вероятно, не заполнит этот буфер и, следовательно, ошибку.

BinaryWriter, BufferedStream или другой, который поддерживает byte[].

+0

Я думаю, что вы правы. Это научит меня копировать и вставлять образец кода на сайт api! Я изменил его, чтобы написать строку вместо байтов. Теперь получаю 404, но я думаю, это потому, что я сейчас подпитываю это поддельное значение, поэтому я правильно помету этот ответ! – James

+0

И это положит конец примерно 4 часам разочарования. Спасибо, Ками! :) – BVernon

15

Не указывайте request.ContentLength = byteArray.Length; перед записью потока запросов. request.ContentLength устанавливается автоматически.

+0

Это был правильный ответ в моем случае. Благодарю вас - Dror – Dror

 Смежные вопросы

  • Нет связанных вопросов^_^