Solving "The underlying connection was closed: An unexpected error occurred on a send." (Webservices)

UPDATE: For solution when using WSE, see here!

Sometimes when you invoke a webservice the call fails with the following exception:

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at ...

In some cases the first call to the webservice works just fine, but if in the following few minutes no new call to the webservice is made, the next call would throw the exception shown above. This problem could be solved by altering the generated proxy class; in the GetWebRequest function the KeepAlive property must be set to false. This can be accomplished by following these steps:

  • Add a Web Reference using the normal way (if you haven't already added one ofcourse).
  • Make sure Show All Files menu item is enable in the Project menu.
  • In the Solution Explorer window, navigate to:
    • Web References
      • <Name of your webservice>
        • Reference.map
          • Reference.cs (or .vb)
  • Open the Reference.cs file and add following code in the webservice proxy class:
    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
     System.Net.HttpWebRequest webRequest =
      (System.Net.HttpWebRequest) base.GetWebRequest(uri);
     webRequest.KeepAlive = false;
     return webRequest;
    }

37 Comments

  • Thanks Jan,

    This was a particularly frustrating problem for me There is a KB article 819450 that is pretty close to what I experienced, except that I had .Net 1.1 installed.

    I could also refresh the page and the request would complete just fine.

    In addition to the solution you mention, I also nested about 3 Try...Catch blocks to have the request &quot;auto-retry&quot;. That way if I mistakenly refreshed the Web Reference, I'd still be covered.

    (As excited as I am about 2.0, it's really cool to see a non-Whidbey solution, too!)



    Thanks! Todd

  • Jan,



    Thanks you saved my bacon today, our webservice keeps timing out over this. I had to convert it to VB.NET cause I don't know C-Shizarp.



    Sample I Used:



    Protected Overrides Function GetWebRequest(ByVal uri As Uri) As System.Net.WebRequest

    Dim webRequest As System.Net.HttpWebRequest = MyBase.GetWebRequest(uri)

    webRequest.KeepAlive = False

    Return webRequest

    End Function

  • I have an application which invokes(calls) a webservice (on IIS 5.0 , windows 2K) every 10 seconds.

    After a long time(about 4 hours),the call to the webservice fails.

    Do you know how to resolve the problem.

  • There seems to be a problem with this solution.

    I use Windows authentication to connect to the service and while dev'ing I use a specific NetworkCredential rather than the default one. It seems by turning the keepalive off, it somehow disables the use of credentials as well.



    Any thoughts?

  • Has anyone resolved the issue of using the KeepAlive=False workaround in conjunction with WSE?

  • I am having the same problem also. When I incorporated the Keep alive chnage it gives me access denied error. I would rellay appreciate if any one help me out on this access denbied issues.



  • We have found a workaround for settings KeepAlive to False with WSE (tested with WSE 1.0 SP1).



    We use reflection to get the underlying HttpWebRequest object through the SoapWebRequest.Request (undocumented and internal) property...



    That's quite ugly, but that works...



    Instead of directly modifying the wrapper class for the web service, we prefer subclassing it as follows :





    using System;

    using System.Net;

    using System.Reflection;



    // Web service reference entered in wizard was &quot;MyWebService.MyWebServiceWse&quot;

    using MyProject.MyWebService;



    namespace MyProject

    {

    public class MySubClassedWebService : MyWebServiceWse {

    private static PropertyInfo requestPropertyInfo = null;



    public MySubClassedWebService(){}



    protected override System.Net.WebRequest GetWebRequest(Uri uri) {

    WebRequest request = base.GetWebRequest(uri);



    if (requestPropertyInfo==null)

    // Retrieve property info and store it in a static member for optimizing future use

    requestPropertyInfo = request.GetType().GetProperty(&quot;Request&quot;);



    // Retrieve underlying web request

    HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request, null);



    // Setting KeepAlive

    webRequest.KeepAlive = false;

    return request;

    }

    }

    }





  • I am having problem getting the Request object from the request object. The return value of request.GetType().GetProperty(&quot;Request&quot;) is coming up as null. Am I doing anything wrong?

  • I think may be I am using WSE2.0 and this property available.

  • MUCHAS GRACIAS to Skeup&amp;Zeb.



    The original MS fix did not work as we are using WSE, however Zeb's Reflection fix seems to make everything right in the world.



    Thanks!!!

  • Schwank,

    When I am trying to execute the follwing line

    requestPropertyInfo = request.GetType().GetProperty(&quot;Request&quot;);

    The requestPropertyInfo does not contain any values. Looks like there is no request property. Am I doing something wrong

  • I did not use the method above exactly as indicated, I stripped the class inheritance and added the code directly to my overridden GetWebRequest method. Code is below...



    protected override System.Net.WebRequest GetWebRequest(Uri uri)

    {

    PropertyInfo requestPropertyInfo = null;



    WebRequest request = base.GetWebRequest(uri);



    if (requestPropertyInfo==null)



    requestPropertyInfo = request.GetType().GetProperty(&quot;Request&quot;);



    // Retrieve underlying web request

    HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request, null);



    // Setting KeepAlive

    webRequest.KeepAlive = false;



    return request;

    }



    Make sure you include the System.Net and System.Reflection namespaces as well. Otherwise the provided code worked brilliantly for me, using WSE 1.0 SP1.

  • I have a similar problem with some of the folks above. Somehow turning keepalive off seems to disrupt my authentication(Windows in my case). What is WSE and is this the solution to my dilemma?

  • saeed,



    Look at the original solution posted by Jan.

    Solutions by Schwank and Skeup&amp;Zeb seem to be a bit overcombinated.



    There is no need to use that property info.

    Just use the request object returned by the call to base.GetWebRequest(uri)





    One more thing. For me changing only .KeepAlive to false didn't help at all.

    However when I changed also .ProtocolVersion to HTTP10 the problem was gone.

  • We have the same problem ! and I tried to fix the problem using the keepalive = false

    Statement I am really frustrated it doesn’t work, our setup contains a sun machine with reverse proxy with .Net application server when the client try to access the web service error message appear saying &quot;The underlying connection was closed: An unexpected error occurred on a send.&quot; Please help….

  • Well, 2 years later, and a big thank you for posting this, as it lead to the solution for figuring out why I was getting a "server committed a protocol violation". Had to set the ProtocolVersion to HttpVersion.Version10.

    Thanks again!

  • The best thing is to copy paste in reference.cs the following code
    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
    System.Net.HttpWebRequest webRequest =
    (System.Net.HttpWebRequest) base.GetWebRequest(uri);
    webRequest.KeepAlive = false;
    return webRequest;
    }


    ...But if you can control the server that are hosting ws and this server is not hosting websites as change enable keep alived connections property to disable and this will solve the bug.
    I have done this...and it works well

  • We are trying to add compression to our WS and we are getting the following error : "The operation has timed-out. ... GetRequestStream()" when the WS make several requests in a short period of time.

    We added the following code to accept compressed response:

    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
    System.Net.WebRequest request = base.GetWebRequest(uri);
    request.Headers.Add("Accept-Encoding", "gzip, deflate");
    return request;
    }

    It seems that the proxy class is trying to open too many connections to the server when the WS asks several requests in a short period of time and it is not capable of reusing the existing open connections, (i read that max persistent connections to a server is 2 by http protocol limitation). I used TcpTrace to verify this. The odd thing is that, when i use tcptrace, several connections (let's say ten, one per request) are opened without problem. Any ideas?

    I tried KeepAlive = false and is not working either.

  • Thank you for this posting. It was very helpful

  • I use the Partial Class mechanism of VB to keep the changes to my web reference in separate file (so if I rebuild the web reference, the changes don't get wiped out).

    The web reference name is NwsNoaa in this example.

    '-------------------------------------
    Imports System.Net
    Imports System.Web.Services.Protocols

    Namespace NwsNoaa

    _
    Partial Public Class ndfdXML
    Inherits SoapHttpClientProtocol

    Protected Overrides Function GetWebRequest(ByVal uri As System.Uri) As System.Net.WebRequest

    Dim w As HttpWebRequest = DirectCast(MyBase.GetWebRequest(uri), HttpWebRequest)
    w.ProtocolVersion = HttpVersion.Version10
    w.KeepAlive = False
    Return w

    End Function

    End Class

    End Namespace

  • i tried everthing u guys have posted above but nothing works for me.
    i m working on .net 1.1 SP1. please help

  • The same for me. I tried all, but nothing works.

  • THE REAL ASP.NET 2.0 SOLUTION:

    I fought this for a while and finally got the right code to fix this problem in ASP.Net 2.0. As many of you know, ASP.Net 2.0 generates the proxy classes dynamically so you can't just simply edit them. The key is in a new feature, 'partial classes'. Below is everything you need to know to fix this in ASP.Net 2.0.

    First, my web reference declaration is:
    weather.ndfdXML

    The standard instantiation would then look like:
    weather.ndfdXML2 wxService = new weather.ndfdXML2();

    With this setup, I ran into the exact same problem everyone else has written about here and rarely solved.

    First, add a new class and make it a partial class (C# code posted):
    using System;
    using System.Net;
    using System.Web.Services.Protocols;

    namespace weather
    {
    public partial class ndfdXML2 : weather.ndfdXML
    {
    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
    //throw new Exception("Custom WebRequest override code hit!!");

    System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
    webRequest.KeepAlive = false;
    webRequest.ProtocolVersion = HttpVersion.Version10;
    return webRequest;
    }
    }
    }

    You can optionally uncomment that new exception to verify that the code is indeed executing.

    Second, change you instantiation inside your code to the following:
    weather.ndfdXML2 wxService = new weather.ndfdXML2();

    Now everything works great!!

  • Excellent!! Works just as Craig describes. Many Thanks.

    I ran into this problem with a C# client and an Axis2c server.

    Thanks again.

  • This post finally solved my issue. You're great- thanks!

    These are now my two solutins to most of my request nightmares:
    WebRequestObject.ServicePoint.Expect100Continue = False
    WebRequestObject.KeepAlive = False

  • Thanks very much - this was a real lifesaver!

  • Hello,

    I just wanted to add to this that I'm using the 2.0 Framework and have upgraded to WSE 3 and am not experiencing the "Invalid Cast" exception. The underlying type has been changed to an HttpWebRequest so it works fine.

    -Sean

  • Hey Thanks a lot Jan.. Your solution has solved my problem :-)


    ~Sanjivani

  • Hi i have a mobile aspx page .. where i will req an url using httpwebrequest and will get the response back and update my db .... In this scenario ... while hittting the page again and again . m getting "underlying connection closed error"... Its coming only when i hit that page simultaneously..
    Do any1 knw any soln apart from setting keepalive = false ....
    its not working in mobile ...

  • All above didnt worked for me!!
    Problem was somewhere else, I installed Safari Browser and Uninstalled it. what this browser did while uninstalling is it cleared all the proxy settings of IE.
    (i.e. Properties >> Connection Settings >> LAN >> Advanced >> Bypass proxy)

    I restored these settings (copiedfrom other machines)

    And Its done

  • i am getting the same problem.

    My webservices are written in ruby, i added the webreference and accessing it from another pc. first it works fine but the next time when i call the method its giving error:
    The underlying connection was closed: An unexpected error occurred on a send." (Webservices). how to solve this issue.

    Thanks in advance.

  • webRequest.ServicePoint.ProtocolVersion = System.Net.HttpVersion.Version10;

    should be

    webRequest.ProtocolVersion = System.Net.HttpVersion.Version10;

  • I'm unclear why people have been able to solve the problem setting the protocol version to 1.0, how exactly does this fix this problem as opposed to using the 1.1 (default?) protocol?

  • Thanks Craig!!!
    You've made my life simple again :)

  • I have a different kind of problem. May be not exactly related to this post. But thought you may be able to provide some help.

    We have a Web application, web services and a windows desktop application. All are .Net based applications.
    Web app abd window desktop app are consuming Web Services.

    Now we are planning to enable SSL on web service. What kind of issue we should expect from this transition.?

    Do we need to make any code changes in Web app, windows app and web services because we are moving from HTTP to HTTPS?

    Thanks

  • Thanks a lot for the helpful posts. My problem has been solved. Mission complete :)

  • Thank you for the fix. You are a God!

Comments have been disabled for this content.