简体   繁体   中英

HttpWebRequest.GetResponse() throws untrappable error

I am testing a web-service app I wrote in C# (Visual Studio 2015) on a Windows 2003 server. The app runs fine, but when I run the line of code:

WebResponse webResponse = request.GetResponse();

where request is an HttpWebRequest instance, the application throws an "Object reference not set to an instance of an object."

Before everyone tells me to go research that error, I have. It doesn't make sense here. The HttpWebRequest is certainly not null, I can access it's properties like URL and UserAgent right before the program crashes. Even more odd, this code is wrapped in a try..catch that traps both web exceptions and general exceptions. I've no idea why it isn't trapping this.

But the reason it is happening is because if I try the URL in Internet Explorer (version 8.0 on this old server), I get an "Internet Explorer cannot display the web page" error. I can't even sign in to the site I wish to access. Firefox works fine, but I don't know how to force HttpWebRequest to "be" Firefox (UserAgent has been set to a standard Mozilla string...).

If the web request layer on this old server just won't work (.NET version is 3.5, by the way), that's fine. But I'd like to be able to trap the error. Why doesn't my try..catch work, and does anyone have any idea what would make this very simple code (that works everywhere else) throw a null object error?

Additional

Here is the whole 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;
    }

Shouldn't the final catch trap any general exceptions? To be clear, the error I see is at RUN-TIME -- I cannot debug on this machine because it does not have Visual Studio on it (and that is not an option). So, I have no idea what the process thinks is null. How can I find that out? The reason I know the line:

WebResponse webResponse = request.GetResponse();

is the problem is because I put messageboxes between each line until I discovered what line was blowing up. Would putting a "Debug" version of the exe in play offer more debugging info when the app crashes? (NOTE: debug version of EXE does not appear to offer any more information, and I cannot add a NullReferenceException because the compiler says the previous "catch" already traps for that...yet it doesn't.).

The answer is...I'm an idiot.

The exception WAS being trapped, it went to the WebException branch, and then errored out in there because within that handler I try:

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

That doesn't work so well when wex.Response is null. And it is null in this case because the request was not establishing a connection in the first place.

A more robust error handler could either nest another try..catch to catch any additional errors, or simply make sure what you are going to use in the handler will always work. I changed my WebException handler to this:

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

and finally got a meaningful error:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

So, it was never getting a connection in the first place, hence no response. This was due to the older IE not supporting HTTPS for this web site. As a quick-and-dirty fix to check if that was the case, I added the catch-all:

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

and BAM! everything worked. I won't leave that in there, since it's not secure, but it did fix the issue.

So, the error was trappable (was trapped, in fact!) and I figured out why the issue arose in the first place. Thanks to everyone for their help!

The request should not be null. WebRequest.Create() should be qualifying your RequestURI and will return the following error Invalid URI: The format of the URI could not be determined . However I've seen other examples where people have gotten round this like " https://helloworld.comFoo/Bar.html ".

The remote name RequestUri may be incorrect and you should test it before calling webRequest.GetResponse() . The method WebRequest.Create() doesn't check this 100%.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM