2009-09-02 80 views

回答

44

好吧,這似乎是一個設計行爲和vexing exception完美的例子。這可以用這個來解決:

public static HttpWebResponse GetHttpResponse(this HttpWebRequest request) 
{ 
    try 
    { 
     return (HttpWebResponse) request.GetResponse(); 
    } 
    catch (WebException ex) 
    { 
     if(ex.Response == null || ex.Status != WebExceptionStatus.ProtocolError) 
      throw; 

     return (HttpWebResponse)ex.Response; 
    } 
} 
+3

這適用於大多數情況,但某些Web服務器在返回404錯誤時可能會返回響應主體。在這種情況下,上面的代碼會將404視爲對待304! – comshak 2010-01-07 20:50:36

+0

@comshak這是一個「很好的瞭解」。調用代碼必須知道什麼是可接受的響應代碼。 – roufamatic 2011-07-06 21:42:22

+1

我也加了'|| ((HttpWebResponse)ex.Response).StatusCode!= HttpStatusCode.NotModified' – 2013-11-25 08:03:08

7

這真是一個令人沮喪的問題,並且可以交替使用下面的擴展方法類和調用request.BetterGetResponse()

//----------------------------------------------------------------------- 
// 
//  Copyright (c) 2011 Garrett Serack. All rights reserved. 
// 
// 
//  The software is licensed under the Apache 2.0 License (the "License") 
//  You may not use the software except in compliance with the License. 
// 
//----------------------------------------------------------------------- 

namespace CoApp.Toolkit.Extensions { 
    using System; 
    using System.Net; 

    public static class WebRequestExtensions { 
     public static WebResponse BetterEndGetResponse(this WebRequest request, IAsyncResult asyncResult) { 
      try { 
       return request.EndGetResponse(asyncResult); 
      } 
      catch (WebException wex) { 
       if(wex.Response != null) { 
        return wex.Response; 
       } 
       throw; 
      } 
     } 

     public static WebResponse BetterGetResponse(this WebRequest request) { 
      try { 
       return request.GetResponse(); 
      } 
      catch (WebException wex) { 
       if(wex.Response != null) { 
        return wex.Response; 
       } 
       throw; 
      } 
     } 
    } 
} 

你讀圍繞工作更多關於它在對這個問題我的博客文章在http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/

3

的方式來避免這種System.WebExceptionAllowAutoRedirect屬性設置爲false。 這會禁用WebRequest的自動重定向邏輯。對於304重定向請求來說,它似乎被破壞了,因爲它並不是最嚴格意義上的真正重定向。 當然,這意味着其他重定向請求3xx必須手動處理。

+1

絕對的輝煌。如果我不需要它,爲什麼我應該爲強力異常機器支付費用? – jsuddsjr 2017-11-03 18:47:08

0

我也碰到這個問題,代碼:

try 
{ 
    ... 
    var webResponse = req.GetResponse(); 
    ... 
} 
catch (WebException ex) 
{ 
    Log.Error("Unknown error occured", ex); 
    //throw; 
} 

,看來,如果遠程服務器拋出這個錯誤或返回定製304返回304個狀態必須被傳遞給瀏覽器,以便瀏覽器可以返回緩存響應。否則,您可能會收到來自遠程服務器的空響應。

所以在我的情況下,與正確的緩存處理正常的行爲應該是這樣的:

try 
{ 
    ... 
    var webResponse = req.GetResponse(); 
    ... 
} 
catch (WebException ex) 
{ 
    if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotModified) 
     throw; 
    Log.Error("Unknown error occured", ex); 
} 
1

正如一個供參考,這是使用C#6(VS2015)when子句Anton Gogolev's answer更新。使用調試器時,它會少一點惱人,因爲它會刪除一個檢查點:

public static HttpWebResponse GetHttpResponse(this HttpWebRequest request) 
{ 
    try 
    { 
     return (HttpWebResponse) request.GetResponse(); 
    } 
    catch (WebException ex) 
     when (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null) 
    { 
     return (HttpWebResponse) ex.Response; 
    } 
} 
相關問題