2012-11-09 71 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";