2009-09-02 12 views

cevap

44

Tamam, bu bir tasarım davranışını ve vexing exception'un mükemmel bir örneği gibi görünüyor. Bu, bu ile çözülebilir:

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

Bu en vakaların çalışır fakat bir 404 hatası döndürürken bazı web sunucuları bir cevap gövdesini geri dönebilirler. Bu durumda, yukarıdaki kod bir 304'ü tedavi ettiği için bir 404'ü tedavi edecektir! – comshak

+0

@comshak, "bilmek güzel." Çağrı kodu, kabul edilebilir cevap kodlarının farkında olmalıdır. – roufamatic

+1

Ben de eklendi || ((HttpWebResponse) ex.Response) .StatusCode! = HttpStatusCode.NotModified' –

7

Bu gerçekten sinir bozucu bir sorundur ve alternatif 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; 
      } 
     } 
    } 
} 

okumak aşağıdaki uzatma yöntemi sınıfını kullanarak ve çağrılarak geçici olarak alınabilir http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/

3

yolu bu konuda benim blog yazısı bu konuda daha fazla bu System.WebExceptionfalse için AllowAutoRedirect özelliğini ayarlamaktır önlemek için. Bu, WebRequest'un otomatik yönlendirme mantığını devre dışı bırakır. 304 yönlendirme istekleri için kırılmış gibi gözüküyor, çünkü en katı anlamda gerçek bir yönlendirme değil. Elbette diğer yönlendirme istekleri 3xx el ile ele alınması gerektiği anlamına gelir.

+1

Kesinlikle harika. İhtiyacım olmasa, ağır elle kullanılan istisna makineleri için neden ödeme yapmalıyım? – jsuddsjr

0

Ben de koduyla bu konuya rastladım:

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

Ve Uzak Sunucu bu hatayı atma veya özel 304 döndürerek o tarayıcıya geçirilmelidir 304 durumunu dönerse bu yüzden Tarayıcı geri dönebilirler anlaşılmaktadır önbelleğe alınmış yanıt. Aksi takdirde, muhtemelen Uzak Sunucudan Yanıtı boşaltabilirsiniz. Sadece bir Bilginize olarak

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

, bu C# 6 (VS2015) when maddesini kullanan Anton Gogolev's answer için bir güncelleme:

Yani taşıma doğru Önbellek normal davranış için benim durumumda bu gibi olmalıdır. O bir catchpoint kaldırır gibi bir hata ayıklayıcı kullanırken biraz daha az sinir bozucu:

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; 
    } 
} 
İlgili konular