2009-09-02 19 views
26

एक वेब सर्वर HTTP 304 (संशोधित नहीं) के साथ HttpWebRequest.GetResponse() का जवाब देता है पर WebException फेंकता है, GetResponse() thows एक WebException, जो मेरे लिए तो बहुत अजीब है। क्या यह डिज़ाइन द्वारा है या क्या मुझे कुछ स्पष्ट याद आ रहा है?HttpWebRequest.GetResponse HTTP 304

उत्तर

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

यह अधिकांश मामलों में काम करता है, लेकिन कुछ वेब सर्वर एक प्रतिक्रिया शरीर लौट सकता है जब एक 404 त्रुटि लौटने। उस स्थिति में, उपरोक्त कोड 404 का इलाज करेगा क्योंकि यह 304 का इलाज करता है! – comshak

+0

@comshak कि "एक जानना अच्छा है।" कॉलिंग कोड को अवगत प्रतिक्रिया कोड के बारे में पता होना चाहिए। – roufamatic

+1

मैंने भी '|| जोड़ा ((HttpWebResponse) ex.Response) .StatusCode! = HttpStatusCode.NotModified' –

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.WebExceptionfalse को AllowAutoRedirect गुण सेट करने के लिए है। यह WebRequest के स्वचालित पुनर्निर्देशन तर्क को अक्षम करता है। ऐसा लगता है कि यह 304 पुनर्निर्देशन अनुरोधों के लिए टूटा हुआ है, क्योंकि यह सख्त अर्थ में वास्तविक पुनर्निर्देशन नहीं है। बेशक इसका मतलब है कि अन्य पुनर्निर्देशन अनुरोध 3xx मैन्युअल रूप से संभाला जाना है।

+1

बिल्कुल शानदार। अगर मुझे इसकी आवश्यकता नहीं है तो मुझे भारी हाथी अपवाद मशीनरी के लिए भुगतान क्यों करना चाहिए? – jsuddsjr

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
बस एक FYI करें के रूप में

, इस Anton Gogolev's answer के लिए एक अद्यतन सी # 6 (VS2015) when खंड का उपयोग करता है है। यह थोड़ा कम कष्टप्रद जब एक डिबगर का उपयोग कर के रूप में यह एक catchpoint को हटा दिया गया है:

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; 
    } 
} 
संबंधित मुद्दे