2015-12-16 42 views
4

我一直在使用.NET 4.5中的HttpClient掙扎了一段時間。在通過分塊傳輸對WebApi端點進行大型流式上傳時,如果服務器已通過非成功狀態代碼(未找到,認證,授權,驗證錯誤等)響應中間請求,則無法停止。HttpClient在收到服務器響應後無法停止流式傳輸

使用ConnectStream類中的調試器查看它知道它從服務器收到了一個不成功的狀態。從服務器接收到的HTTP狀態和數據將被存儲以備後用,並且從那時起它只是假裝從流中讀取直到結束。從那時起,線路上沒有任何信息被寫入,並且後來通過HttpResponseMessage提供了響應。這種無法解釋的行爲給我造成了巨大的問題,因爲所涉及的流可能非常大。花費無用的時間讀取流直到結束,並向用戶顯示不正確的上載報告。我停止了Web服務器,遠程機器,甚至禁用了本地網絡接口。 HttpClient不在乎。它不斷從提供的流中讀取數據。

我試過HttpCompletionOption.ResponseHeadersReadStreamedContentPushStreamContent。同樣的行爲。我也嘗試過使用HttpWebRequest,但是它不允許在輸出流上寫入並同時讀取傳入流。有什麼辦法阻止客戶端在收到服務器響應後發送或假裝發送流?爲什麼HttpClient的行爲如此?

var httpClientHandler = new WebRequestHandler 
    { 
     AllowAutoRedirect = true, 
     PreAuthenticate = false, 
     CookieContainer = cookieContainer, 
     UseCookies = true, 
     CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore),           
     AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip 
    }; 
var httpClient = new HttpClient(_httpClientHandler) 
    { 
      BaseAddress = baseApiUrl,         
      Timeout = Timeout.InfiniteTimeSpan; 
    }; 
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true; 
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain", 0.8)); 
httpClient.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("UTF-8")); 
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(appName, appVersion)); 

var requestContent = new StringContent(serializedRequest, Encoding.UTF8, "application/json"); 

// the monitored stream is an implementation of the stream that proxies the calls to a classic file stream 
// here I monitor the calls made to Read(byte[] buffer, int offset, int count) method 
// tried with both CanSeek = false or true - the HttpClient reads the whole stream no matter what. 
var streamedContent = new StreamContent(monitoredStream); 
streamedContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") 
    { 
     FileName = "upload.bin", 
     Size = monitoredStream.Length  
    }; 

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, relativeUrl) 
    { 
     Content = new MultipartFormDataContent 
      { 
       requestContent, 
       streamedContent  
      } 
    }; 

// the Owin middleware could fail checking authentication, an authorization error could occur, 
// or the WebApi controller could receive the first part of the multipart data and reject the request 
// from the moment data was received from the server, mid-stream, I could safely unplug the network cable 
// socket erros are being ignored, actually the underlying socket is no longer used 
// the response message contains the status code and data received during the transmission of the request at the end of this call 
var httpResponseMessage = await _httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken); 
+0

你能顯示你的代碼嗎? – Kamo

回答

相關問題