【问题标题】:HttpWebRequest.GetResponse() throws untrappable errorHttpWebRequest.GetResponse() 抛出无法捕获的错误
【发布时间】:2015-09-01 14:28:35
【问题描述】:

我正在 Windows 2003 服务器上测试我用 C# (Visual Studio 2015) 编写的 Web 服务应用程序。该应用程序运行良好,但是当我运行代码行时:

WebResponse webResponse = request.GetResponse();

如果 request 是一个 HttpWebRequest 实例,应用程序会抛出“未设置对象实例的对象引用”。

在每个人都告诉我去研究那个错误之前,我已经知道了。这里没有意义。 HttpWebRequest 肯定不为空,我可以在程序崩溃之前访问它的属性,如 URL 和 UserAgent。更奇怪的是,这段代码被包裹在一个 try..catch 中,它同时捕获了 Web 异常和一般异常。我不知道为什么它没有捕获这个。

但发生这种情况的原因是,如果我在 Internet Explorer(此旧服务器上的 8.0 版)中尝试 URL,我会收到“Internet Explorer 无法显示网页”错误。我什至无法登录我想访问的网站。 Firefox 工作正常,但我不知道如何强制 HttpWebRequest “成为”Firefox(UserAgent 已设置为标准 Mozilla 字符串...)。

如果这台旧服务器上的 Web 请求层无法正常工作(顺便说一下,.NET 版本是 3.5),那很好。但我希望能够捕获错误。为什么我的 try..catch 不起作用,有没有人知道是什么让这个非常简单的代码(在其他任何地方都可以使用)抛出空对象错误?

附加

这是整个 try..catch:

    try
    {
        HttpWebRequest request = GenerateWebRequest(pcMethodName, pcCommand, pcHTTPMethod);
        MessageBox.Show(request.RequestUri.ToString());
        WebResponse webResponse = request.GetResponse();
        MessageBox.Show("The above line worked!");
        StreamReader reader = new StreamReader(webResponse.GetResponseStream());
        lcResult = reader.ReadToEnd();
    }
    catch (WebException wex)
    {
        lcResult = "ERROR (web exception): " + Environment.NewLine + new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
    }
    catch (Exception ex)
    {
        lcResult = "ERROR (general exception): " + Environment.NewLine + ex.Message;
    }

最终的 catch 不应该捕获任何一般异常吗?需要明确的是,我看到的错误是在运行时——我无法在这台机器上调试,因为它没有 Visual Studio(这不是一个选项)。所以,我不知道这个过程认为什么是空的。我怎样才能知道呢?我知道这条线的原因:

WebResponse webResponse = request.GetResponse();

问题是因为我在每一行之间放置了消息框,直到我发现哪一行被炸毁了。当应用程序崩溃时,运行“调试”版本的 exe 是否会提供更多调试信息? (注意:EXE 的调试版本似乎没有提供更多信息,我无法添加NullReferenceException,因为编译器说之前的“catch”已经捕获了这个......但它没有。)。

【问题讨论】:

  • 你能发布你的try..catch吗?如果您正在捕获“网络异常和一般异常”,您是否正在捕获 NullReferenceExceptions?此外,当您捕捉到 webexception 时,您是否输出了响应,服务器会告诉您什么?
  • VS 告诉你什么是空的?
  • Exception 的一般捕获将捕获 NRE @garyamorris。除非我误解了你的评论
  • 我正在检查他是如何捕捉“一般异常”的,我认为这意味着 Exception 但总是值得检查。
  • 我在原始帖子中添加了更多信息——任何人都可以看到更多可能发生的事情,最重要的是,看看为什么我无法捕获异常?

标签: c# web null request


【解决方案1】:

答案是……我是个白痴。

异常被捕获,它进入 WebException 分支,然后在那里出错,因为在那个处理程序中我尝试:

lcResult = "ERROR (web exception): " + Environment.NewLine + new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();

当 wex.Response 为 null 时,效果就不太好了。在这种情况下它为空,因为请求一开始没有建立连接。

更强大的错误处理程序可以嵌套另一个 try..catch 以捕获任何其他错误,或者只是确保您将在处理程序中使用的内容始终有效。我将我的 WebException 处理程序更改为:

    catch (WebException wex)
    {
        if (wex.Response != null)
        {
            lcResult = "ERROR (web exception, response generated): " + Environment.NewLine + new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
        }
        else
        {
            lcResult = "ERROR (web exception, NO RESPONSE): " + wex.Message + wex.StackTrace;
        }
    }

最后得到一个有意义的错误:

底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。

所以,它一开始就没有建立连接,因此没有响应。这是由于旧版 IE 不支持该网站的 HTTPS。作为检查是否是这种情况的快速而肮脏的修复方法,我添加了全部内容:

System.NetServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

然后砰!一切正常。我不会把它留在那里,因为它不安全,但它确实解决了问题。

所以,错误是可捕获的(实际上是被捕获了!),我首先弄清楚了为什么会出现问题。感谢大家的帮助!

【讨论】:

    【解决方案2】:

    请求不应为空。 WebRequest.Create() 应该符合您的 RequestURI 并且将返回以下错误 Invalid URI: The format of the URI could not be determined。然而,我见过其他例子,人们已经绕过这个,比如“https://helloworld.comFoo/Bar.html”。

    远程名称RequestUri 可能不正确,您应该在调用webRequest.GetResponse() 之前对其进行测试。 WebRequest.Create() 方法没有检查这个 100%。

    【讨论】:

    • 我不确定你的意思。我该如何测试 RequestURI,究竟是什么?在我的程序中,我有一个消息框在出错的行之前显示 URL(这都是运行时出错——我无法调试它),并且 URL 看起来很好。事实上,该 URL 也被保存到一个文本框中,然后我可以将该 URL 复制并粘贴到 Firefox 中——它工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2011-09-07
    相关资源
    最近更新 更多