【问题标题】:How can I catch a 404?我怎样才能捕捉到 404?
【发布时间】:2010-12-29 07:23:39
【问题描述】:

我有以下代码:

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 等等。

【问题讨论】:

  • NNNOOOOOOOOOOOOOOO! 不要捕获System.Exception,也不要依赖处理程序中的异常文本!
  • 约翰桑德斯的回答是最完整的。我认为人们只是出于恶意而对他投了反对票。
  • 不要使用throw ex,您将生成一个带有空调用堆栈的新异常。只需使用throw
  • 我自己一直觉得这很令人沮丧。如果您得到格式正确的响应,则不应抛出异常,并且协议错误消息绝对格式正确。该类应允许用户解释结果并采取相应的行动。
  • @JeremyHolovacs 在较新的 http 客户端中不再抛出类似 404 的异常。 “不要为控制流使用异常”似乎没能在构建WebRequest的团队中幸存下来@

标签: c# .net exception-handling error-handling http-status-code-404


【解决方案1】:

我认为,如果您收到 WebException,其中有一些信息可以用来确定它是否是 404。这是我目前知道的唯一方法...我很想知道其他...

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

【讨论】:

    【解决方案2】:

    使用HttpStatusCode Enumeration,特别是HttpStatusCode.NotFound

    类似:

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

    其中
    weWebException

    【讨论】:

    • 我可以在不创建自己的查找列表的情况下以某种方式从对象中获取 NUMBER 吗?我想要类似的东西: int httpresponsecode = HttpStatusCode.ToInt() 或类似的,所以我得到 404
    • @BerggreenDK 你应该可以只做 int httpresonsecode = (int) HttpStatusCode.NotFound
    • -1 对我的古老投票的部分解释:如果由于某种原因,we.Response 不是HttpWebResponse,代码将抛出 NullReferenceException。如果代码希望假定它始终具有该类型,那么它应该简单地转换:HttpWebResponse errorResponse = (HttpWebResponse)we.Response;。如果不可能发生,这将抛出一个明确的InvalidCastException,而不是一个神秘的NullReferenceException
    • 我使用此代码得到An object reference is required for the non-static field, method, or property 'WebException.Response'
    【解决方案3】:

    看看这个片段。 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

    【讨论】:

      【解决方案4】:

      请参阅MSDN 了解响应状态:

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

      【讨论】:

      • @John Saunders - 我很乐意将它传递给 MSDN(我从那里复制了示例......)。这段代码的目的是为了展示StatusCode的用法,并不是尽可能的高效。
      • @John Saunders - 我只留下了我想展示的部分,只为你:-)
      【解决方案5】:

      我还没有测试过,但它应该可以工作

      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;
      }
      

      【讨论】:

      • @John Saunders - 我正在调整 OP 的代码,而不是优化它。
      • @John - 也许我只是希望他们复制/粘贴catch 块,因为我在尝试中的代码与 OP 完全相同。由于OP的代码,您真的应该完全拒绝这个问题。
      • @John 我们忘了这里是示例代码。这是404的另一种方式,而不是如何使用GetResponse。 -1 似乎有点苛刻。为 Miff 回答问题 +1。
      • @John 我认为您在评论中指出这一点很好。我看待否决投票的方式是,如果给出的代码不能解决问题。感谢您删除反对票。
      • @John - 很好,我把所有东西都扔掉了,现在开心了吗?
      【解决方案6】:

      捕获正确的异常类型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");
      }
      

      【讨论】:

      • @John Saunders 我不在那里辩论你,但这不是问题,他问了捕获 404 的最佳方法。我对他的代码的更改仅限于回答问题,使更改尽可能简单明了。
      • @John Saunders:固定,我想“如果这是最有效的”使它适用于这个问题。
      • 只需将e.Response 转换为HttpWebResponse 即可访问StatusCode
      【解决方案7】:
      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
          }
      }
      

      【讨论】:

      • 大声笑 @ 成为 IDisposable 警察并给每个人一个-1,因为没有将响应包装在 using 块中。
      • 这是一项艰巨的工作,但有人必须这样做。 OTOH,我几乎没有添加这个答案,因为我似乎在叮嘱其他所有人,以使我的答案成为最受好评的答案。
      • 我实际上投了赞成票,但我只注意到一件事:catch 的末尾可能应该有一个throw(重新抛出),否则这只会默默地吃掉任何其他类型的@ 987654324@.
      • @John Saunders:为什么你的请求也没有 using ?
      • @Joel: WebRequest 没有实现 IDisposable
      【解决方案8】:

      对于浏览此内容的 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
      

      【讨论】:

        【解决方案9】:

        在 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
        }
        

        【讨论】:

        • 我一直忽略的一个非常酷的功能!我一直在寻找仅捕获 401 的方法,同时让其他人通过通用异常处理程序。这是要走的路!
        【解决方案10】:

        当使用 WebRequest 类 POST 或 GET 数据到服务器时,异常类型将是 WebException。下面是文件未找到异常的代码

                //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);
                            }
        
                        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-18
          相关资源
          最近更新 更多