Exception:"The request was aborted: The connection was closed unexpectedly" When invoking two methods same object

StackOverflow https://stackoverflow.com/questions/17844929

  •  04-06-2022
  •  | 
  •  

Question

I am having a problem that many people have experienced but all of the solution that are available online are specific to their scenarios. I have tried the suggestions available but still no luck wha I have tried was:

1.) req.KeepAlive = false;
2.) req.ProtocolVersion = HttpVersion.Version10; (this solved a different exception that I was getting)

I have two methods passing XML string to the server and getting responses back the two methods are:

public string userDeviceQuery(string userID)
    {
        string query = "xml=<query>";
        query += "<appInfo>";
        query += "<appID>" + appID + "</appID>";
        query += "<appCertificate>" + appCertificate + "</appCertificate>";
        query += "</appInfo>";
        query += "<userDevicesQuery>";
        query += "<userID>";
        query += userID;
        query += "</userID>";
        query += "</userDevicesQuery>";
        query += "</query>";

        using (Stream str = req.GetRequestStream())
        {
            str.Write(System.Text.Encoding.ASCII.GetBytes(query), 0, query.Length);
        }

        WebResponse res = req.GetResponse();

        string stringResponse;
        using (StreamReader reader = new StreamReader(res.GetResponseStream()))
        {
            stringResponse = reader.ReadToEnd();
        }

        string result = parseDeviceQueryRes(stringResponse);
        return result;
    }

AND

public void logoutOfEM(string deviceName)
    {
        string lgRequest = "xml=<request>";
               lgRequest += "<appInfo>";
               lgRequest += "<appID>" + appID + "</appID>";
               lgRequest += "<appCertificate>" + appCertificate + "</appCertificate>";
               lgRequest += "</appInfo>";
               lgRequest += "<logout>";
               lgRequest += "<deviceName>";
               lgRequest += deviceName;
               lgRequest += "</deviceName>";
               lgRequest += "</logout>";
               lgRequest += "</request>";

         using (Stream str = req.GetRequestStream())
        {
            str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
        }

        WebResponse res = req.GetResponse();

        using (StreamReader reader = new StreamReader(res.GetResponseStream()))
        {
            stringResponse = reader.ReadToEnd();
        }
        string stringResponse = reader.ReadToEnd();
    }

They are both part of a class called EMAPI. I can use both methods just fine separately but if try to use them back-to-back with the same object representing EMAPI I get the exception described above. I am not sure what is causing the connection to close, I would like to be able to keep it open and close it using a de-constructor if possible.

For those who are curious this code deals with Cisco Extension Mobility API, first method queries the server to get a device you are logged in, second method logs teh user out of that device.

Thanks for the help.

Was it helpful?

Solution

Use a different HttpWebRequest for each method. You should not reuse the HttpWebRequest object for different requests. Check this: Can I reuse HttpWebRequest without disconnecting from the server?. Internally, .NET can decide to reuse the connection to the same server if possible, but the server can decide to close the connection after each request, even if you specify req.KeepAlive = true.

Also make sure you dispose/close your WebResponse object in your methods.

OTHER TIPS

I would be using the 'using' keyword around all of my IDisposables first off. Secondly looks like you are leave the StreamReaders open.

Edit

To answer you comment about using keyword.

Instead of this:

Stream str = req.GetRequestStream();
str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
str.Close();

Write it this way:

using(Stream str = req.GetRequestStream())
{
    str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
}

The using keyword will automatically handle all IDisplosable task for you.

I just noticed something your code and why I thought you weren't closing. You are calling close and then trying to ready the lines. This is a good example of why to get into the habit of using the 'using' keyword.

StreamReader reader = new StreamReader(res.GetResponseStream());
reader.Close(); //Calling CLOSE before trying to use the reader
string stringResponse = reader.ReadToEnd();

ANOTHER EDIT

public void logoutOfEM(string deviceName)
    {
        string lgRequest = "xml=<request>";
               lgRequest += "<appInfo>";
               lgRequest += "<appID>" + appID + "</appID>";
               lgRequest += "<appCertificate>" + appCertificate + "</appCertificate>";
               lgRequest += "</appInfo>";
               lgRequest += "<logout>";
               lgRequest += "<deviceName>";
               lgRequest += deviceName;
               lgRequest += "</deviceName>";
               lgRequest += "</logout>";
               lgRequest += "</request>";
     using (Stream str = req.GetRequestStream())
    {
        str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
    }

    WebResponse res = req.GetResponse();

    var response = string.Empty;
    using(StreamReader reader = new StreamReader(res.GetResponseStream()))
    {
        response = reader.ReadToEnd();
    }


}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top