75

我有以下代码:我怎样才能抓住404?

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
request.Method = "HEAD"; 
request.Credentials = MyCredentialCache; 

try 
{ 
    request.GetResponse(); 
} 
catch 
{ 
} 

我如何能赶上一个特定的404错误? WebExceptionStatus.ProtocolError只能检测到发生错误,但不能提供错误的确切代码。

例如:

catch (WebException ex) 
{ 
    if (ex.Status != WebExceptionStatus.ProtocolError) 
    { 
     throw ex; 
    } 
} 

是不足够有用的......协议的例外可能是401,503,403,什么真正的。

+11

** NNNOOOOOOOOOOOOO!**不要抓住'System.Exception',也不要依赖处理程序中的异常文本! – Aaronaught 2010-01-28 16:09:02

+2

那么你会推荐什么? – Luke101 2010-01-28 16:11:17

+2

约翰桑德斯的答案是最完整的。我认为人们只是在恶意中低估了他。 – Aaronaught 2010-01-28 16:15:45

回答

92

使用HttpStatusCode Enumeration,具体HttpStatusCode.NotFound

喜欢的东西:

HttpWebResponse errorResponse = we.Response as HttpWebResponse; 
if (errorResponse.StatusCode == HttpStatusCode.NotFound) { 
    // 
} 

w ^这里
weWebException

+0

是的,这是理想的...像魅力一样工作,再次感谢! – 2009-12-22 22:35:14

+0

我可以从对象中以某种方式获得NUMBER,而无需创建自己的查找列表?我想有这样的东西:int httpresponsecode = HttpStatusCode.ToInt()或类似的,所以我得到404 – BerggreenDK 2011-04-12 14:42:11

+2

@BerggreenDK你应该能够做int httpresonsecode = **(int)** HttpStatusCode.NotFound – Trev 2012-03-14 14:30:08

4

我想如果你发现了WebException那里有一些信息可以用来确定它是否是404这是我现在唯一知道的唯一方法我有兴趣知道任何其他...

catch(WebException e) { 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
     var statusCode = (HttpWebResponse)e.Response).StatusCode); 
     var description = (HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
2

看看这个snipit。 GetResponse会抛出WebRequestException。抓住这一点,你可以从响应中获得状态码。

try { 
    // Create a web request for an invalid site. Substitute the "invalid site" strong in the Create call with a invalid name. 
    HttpWebRequest myHttpWebRequest = (HttpWebRequest) WebRequest.Create("invalid site"); 

    // Get the associated response for the above request. 
    HttpWebResponse myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse(); 
    myHttpWebResponse.Close(); 
} 
catch(WebException e) { 
    Console.WriteLine("This program is expected to throw WebException on successful run."+ 
         "\n\nException Message :" + e.Message); 
    if(e.Status == WebExceptionStatus.ProtocolError) { 
     Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode); 
     Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription); 
    } 
} 
catch(Exception e) { 
    Console.WriteLine(e.Message); 
} 

这个来自http://msdn.microsoft.com/en-us/library/system.net.webexception.status.aspx

2

看到MSDN关于响应的状态:

... 
catch(WebException e) { 
    Console.WriteLine("The following error occured : {0}",e.Status); 
} 
... 
+2

@John Saunders - 我很乐意将它传递给MSDN(我从那里复制了样本...)。 此代码的目的是显示StatusCode的用法,而不是尽可能高效。 – Dror 2010-01-28 09:04:50

+1

@John Saunders - 我只留下了我想展示的部分,只为你:-) – Dror 2010-01-28 16:09:35

13

我没有测试过这一点,但它应该工作

try 
{ 
    // TODO: Make request. 
} 
catch (WebException ex) 
{ 
    if (ex.Status == WebExceptionStatus.ProtocolError) { 
     HttpWebResponse resp = ex.Response as HttpWebResponse; 
     if (resp != null && resp.StatusCode == HttpStatusCode.NotFound) 
     { 
      // TODO: Handle 404 error. 
     } 
     else 
      throw; 
    } 
    else 
     throw; 
} 
+0

@John Saunders--我正在调整OP的代码,而不是优化它。 – MiffTheFox 2010-01-27 19:24:19

+0

@John - 也许我只希望他们复制/粘贴'catch'块,因为我在测试中使用与OP完全相同的代码。你应该完全否认这个问题,因为OP的代码是完全的。 – MiffTheFox 2010-01-28 15:58:48

+1

@John这里我们忘记了示例代码。这是情况,它是404的另一种方式,而不是如何使用GetResponse。 -1似乎有点苛刻。 +1给Miff回答这个问题。 – 2010-01-28 17:38:28

1

赶上正确的异常类型WebException

try 
{ 
    var request = (HttpWebRequest) WebRequest.Create(String.Format("http://www.gravatar.com/avatar/{0}?d=404", hashe)); 

    using(var response = (HttpWebResponse)request.GetResponse()) 
     Response.Write("has avatar"); 
} 
catch(WebException e) 
{ 
    if(e.Response.StatusCode == 404) 
    Response.Write("No avatar"); 
} 
+0

@John Saunders我没有在那里辩论你,但那不是问题,他问了捕获404的最佳方法。我对他的代码的更改仅限于回答问题,以便使更改变得简单明了尽可能。 – 2010-01-27 18:46:07

+0

@John Saunders:固定的,我想“如果这是最高效的”使它适用于这个问题。 – 2010-01-27 18:59:43

111
try 
{ 
    var request = WebRequest.Create(uri); 
    using (var response = request.GetResponse()) 
    { 
     using (var responseStream = response.GetResponseStream()) 
     { 
      // Process the stream 
     } 
    } 
} 
catch (WebException ex) 
{ 
    if (ex.Status == WebExceptionStatus.ProtocolError && 
     ex.Response != null) 
    { 
     var resp = (HttpWebResponse) ex.Response; 
     if (resp.StatusCode == HttpStatusCode.NotFound) 
     { 
      // Do something 
     } 
     else 
     { 
      // Do something else 
     } 
    } 
    else 
    { 
     // Do something else 
    } 
} 
+10

lol @作为一次性警察,并且给予每个人一个-1以便在使用区块中包装回应。 – Rich 2010-01-27 18:32:59

+2

这是一项艰巨的工作,但是_someone_必须这样做。 OTOH,我几乎没有添加这个答案,因为看起来我正在嘲笑其他人让我成为最受好评的答案。 – 2010-01-27 18:38:34

+3

我其实是upvoted的,但我只注意到一件事:应该在'catch'的末尾有'throw'(rethrow),否则这只会默默地吃任何其他类型的'WebException'。 – Aaronaught 2010-01-28 16:17:08

2

对于VB.NET乡亲浏览此,我相信我们可以捕获该异常,只有当它是一个真正的404是这样的:

Try 
    httpWebrequest.GetResponse() 
Catch we As WebException When we.Response IsNot Nothing _ 
           AndAlso TypeOf we.Response Is HttpWebResponse _ 
           AndAlso (DirectCast(we.Response, HttpWebResponse).StatusCode = HttpStatusCode.NotFound) 

    ' ... 

End Try 
+0

你_believe_你可以吗?请尝试一下,然后说“是”或“否”。 – 2014-07-09 19:31:41

10

在C#6你可以使用exception filters

try 
{ 
    var request = WebRequest.Create(uri); 
    using (var response = request.GetResponse()) 
    using (var responseStream = response.GetResponseStream()) 
    { 
     // Process the stream 
    } 
} 
catch(WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) 
{ 
    // handle 404 exceptions 
} 
catch (WebException ex) 
{ 
    // handle other web exceptions 
} 
+0

我已经忽略了一个非常酷的功能!我一直在寻找方法来捕获只有401而让别人通过一般的异常处理程序。这是要走的路! – 2017-02-08 03:55:03

0

当POST或GET使用WebRequest类则异常的类型将是WebException.Below是代码数据服务器文件未发现异常

 //Create a web request with the specified URL 
      string path = @"http://localhost/test.xml1"; 
      WebRequest myWebRequest = WebRequest.Create(path); 

     //Senda a web request and wait for response. 
       try 
       { 
        WebResponse objwebResponse = myWebRequest.GetResponse(); 
        Stream stream= objwebResponse.GetResponseStream(); 

       } 
       catch (WebException ex) { 
        if (((HttpWebResponse)(ex.Response)).StatusCode == HttpStatusCode.NotFound) { 
         throw new FileNotFoundException(ex.Message); 
        } 

       }