2012-11-09 72 views
0

我正在使用函數來檢查外部url是否存在。以下是爲了清楚起見刪除了狀態消息的代碼。使用httpwebrequest檢查url是否存在

public static bool VerifyUrl(string url) 
    { 
     url.ThrowNullOrEmpty("url"); 

     if (!(url.StartsWith("http://") || url.StartsWith("https://"))) 
      return false; 

     var uri = new Uri(url); 

     var webRequest = HttpWebRequest.Create(uri); 
     webRequest.Timeout = 5000; 
     webRequest.Method = "HEAD"; 

     HttpWebResponse webResponse; 
     try 
     { 
      webResponse = (HttpWebResponse)webRequest.GetResponse(); 
      webResponse.Close(); 
     } 
     catch (WebException) 
     { 
      return false; 
     } 

     if (string.Compare(uri.Host, webResponse.ResponseUri.Host, true) != 0) 
     { 
      string responseUri = webResponse.ResponseUri.ToString().ToLower(); 

      if (responseUri.IndexOf("error") > -1 || responseUri.IndexOf("404.") > -1 || responseUri.IndexOf("500.") > -1) 
       return false; 
     } 

     return true; 
    } 

我對一些外部網址進行了測試,發現大約有20個出現錯誤。如果我添加一個用戶代理,錯誤率約爲14%。

返回的錯誤是「禁止的」,儘管這可以使用用戶代理,「服務不可達」,「不允許的方法」,「未實現」或「連接關閉」解決6%。

有什麼我可以做我的代碼,以確保更多,最好都給出了有效的迴應他們的存在?

另外,可以購買更有效地執行此操作的代碼。

更新 - 12年11月14日----------------------------------------- -----------------------------

在聽從以前的迴應者的建議後,我現在處於一種情況,返回服務不可用的單個域(503)。我有的例子是www.marksandspencer.com。

當我使用這個httpsniffer web-sniffer.net而不是在這個線程推薦的,它的工作原理,使用webrequest.GET返回數據,但我不能解決我需要做什麼,使其工作在我的代碼。

+4

您是否嘗試過使用'GET'而不是'HEAD'?可能有些網絡服務器正在阻止HEAD請求,但我不確定。我發現這個簡單的網站在線測試:http://www.rexswain.com/httpview.html – Davio

+0

該工具是好的 - 幫助我解決一個問題。亞馬遜不允許頭部請求,但確實允許獲取請求。在亞馬遜平臺上託管的Marks&Spencer在兩種情況下都返回暫時不可用的serice。 – dotnetnoob

+0

好吧,這只是意味着錯誤是在他們的最後,或者你沒有一個活動的會話或東西。 – Davio

回答

0

我終於到了bieng的地步,能夠毫無例外地驗證所有的url。

首先我拿了Davios的建議。有些域在Request.HEAD上返回錯誤,因此我已經爲特定場景包含重試。這爲第二個請求創建了一個新的Request.GET。其次,亞馬遜的情況。亞馬遜間歇性地爲自己的網站返回了503錯誤,並且在Amazon框架上託管的網站出現了永久性503錯誤。

經過一番挖掘,我發現將下面一行添加到請求解決了這兩個問題。它是Firefox使用的接受字符串。

var request = (HttpWebRequest)HttpWebRequest.Create(uri); 
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";