2014-01-22 61 views
4

我正在使用HttpClient將數據發送到使用PutAsync的HTTP服務器。服務器在寫入響應頭後關閉連接時發生HttpClient異常

當服務器發回錯誤代碼(例如401 Unauthorized)時,它關閉連接(在其響應中提供了Connection:close標頭)。發生這種情況時,HttpClient拋出System.Net.Http.HttpRequestException(將內容複製到流時出錯),並列出下面列出的內部異常。這似乎與將數據寫出(儘管它在BeginRead中)有關,因爲如果我說服服務器讀取所有要發送的數據,則不會拋出異常。

我可以通過使用HttpClient.SendAsyncHttpCompletionOption.ResponseHeadersRead參數完成相同的任務來解決此問題。在這種情況下,不會拋出異常,我可以閱讀HttpResponseMessage.StatusCode

我的問題是,是正確的例外?即服務器是否不遵守標準,通過關閉連接而不讀取所有不需要的數據?如果不是,那麼PutAsync有沒有問題,因爲在這種情況下它不允許訪問返回StatusCode

樣品的編號:

using (FileStream stream = File.OpenRead(FilePath)) 
using (StreamContent content = new StreamContent(stream)) 
using (HttpRequestMessage req = new HttpRequestMessage 
    { 
     Method = HttpMethod.Put, 
     RequestUri = new Uri(baseUri, Path), 
     Content = content, 
    }) 
using (HttpClient client = new HttpClient()) 
{ 
    req.Content.Headers.ContentType = new MediaTypeHeaderValue(FileContentType); 
    // This version works: 
    //using (HttpResponseMessage resp = await client.SendAsync(req, 
    // HttpCompletionOption.ResponseHeadersRead)) 
    // This version throws an exception: 
    using (HttpResponseMessage resp = await client.PutAsync(
     new Uri(baseUri, Path), content)) 
    { 
     if (resp.StatusCode == HttpStatusCode.Unauthorized) 
     { 
      // Try again with authorisation credentials based on resp.Headers.WwwAuthenticate 
     } 
    } 
} 

內部異常信息:System.IO.IOException(無法讀取從傳輸連接數據:一個現有的連接被強行關閉遠程主機)

at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
at System.Net.PooledStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
at System.Net.ConnectStream.BeginReadWithoutValidation(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state) 
at System.Net.Http.StreamToStreamCopy.StartRead() 

內部異常:System.Net.Sockets.SocketException(現有連接被遠程主機強制關閉)

at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state) 
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) 

回答

0

嘗試使用HTTP協議版本1.0,如果它適合您的需要:

using (HttpRequestMessage req = new HttpRequestMessage 
    { 
     Method = HttpMethod.Put, 
     RequestUri = new Uri(baseUri, Path), 
     Content = content, 
     Version = HttpVersion.Version10 
    }) 
相關問題