2013-09-26 73 views
5

Tôi đã thực hiện một chút tìm kiếm và hầu hết mọi người dường như nhấn vào đây khi gửi lượng dữ liệu lớn hơn, nhưng tôi thì không.Không thể đóng luồng cho đến khi tất cả các byte được viết (API GoodData)

Tôi đang thực hiện một yêu cầu đến một API như sau:

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

Trường hợp ngoại lệ xảy ra trên khung đóng cửa cuối cùng:

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

Bất kỳ manh mối? Cụ thể là tôi đang cố sử dụng lệnh API GoodData xtab2/executor3 - xem http://docs.gooddata.apiary.io/

Nếu tôi xóa "set ContentLength" Tôi nhận được yêu cầu không hợp lệ 400. Nếu tôi đặt thành 0 như yêu cầu GET trước đó (hoạt động tốt), tôi nhận được một lỗi mà tôi đã cố gắng viết nhiều hơn chiều dài của bộ đệm, điều này có ý nghĩa.

Bit bị bẻ cong!

Trả lời

3

Đã xem qua tài liệu - System.IO.StreamWriter.Write() - Có vẻ như không phải là phương thức viết byte.

Phương thức duy nhất phù hợp với chữ ký là - StreamWriter.Write(Object). Tuy nhiên, điều này gọi ToString() trên đối tượng và viết đầu ra; Mà không phải là những gì bạn muốn.

Khi bạn đang đặt bộ đệm đầu ra; luồng đang chờ bộ đệm này được lấp đầy. Tuy nhiên, Object.ToString() có thể sẽ không lấp đầy bộ đệm này và do đó có lỗi.

Sử dụng BinaryWriter, BufferedStream hoặc cách khác hỗ trợ ghi byte[].

+0

Tôi nghĩ bạn nói đúng. Điều đó sẽ dạy tôi sao chép và dán mã mẫu trên trang web api! Tôi đã thay đổi nó để viết chuỗi thay vì các byte. Bây giờ nhận được một 404, nhưng tôi nghĩ rằng đó là bởi vì tôi đang cho nó một giá trị giả mạo cho bây giờ, vì vậy tôi sẽ đánh dấu câu trả lời này chính xác! – James

+0

Và điều này đặt dấu chấm hết khoảng 4 giờ thất vọng. Cảm ơn Kami! :) – BVernon

15

Không được đặt request.ContentLength = byteArray.Length; trước khi viết luồng yêu cầu. request.ContentLength được đặt tự động.

+0

Đây là câu trả lời đúng trong trường hợp của tôi. Cảm ơn bạn - Dror – Dror

Các vấn đề liên quan