Solving "The underlying connection was closed" when using WSE

Some time ago I've posted a code snippet to solve following exception which in some cases can happen when you're calling a web service:

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 ...

It seems that this exception also pops up when using Web Services Enhancements (WSE), but the solution I provided doesn't work in that case. You can't get directly to the underlying HttpWebRequest to set the KeepAlive property to false. But recently some people posted two solutions in the comments, so all kudos goes to these people, this time I'm just the messenger! Both solutions use Reflection to get a hold of the HttpWebRequest, nice work!

Solution by Skeup&Zeb
using System;
using System.Net;
using System.Reflection;

// Web service reference entered in wizard was "MyWebService.MyWebServiceWse"
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("Request");

            // Retrieve underlying web request 
            HttpWebRequest webRequest = 
            (HttpWebRequest)requestPropertyInfo.GetValue(request,null);

            // Setting KeepAlive 
            webRequest.KeepAlive = false; 
            return request; 
        } 
    }
}

Solution by Schwank:
protected override System.Net.WebRequest GetWebRequest(Uri uri)

    PropertyInfo requestPropertyInfo = null;

    WebRequest request = base.GetWebRequest(uri);

    if (requestPropertyInfo==null)

    requestPropertyInfo = request.GetType().GetProperty("Request");

    // Retrieve underlying web request 
    HttpWebRequest webRequest = (HttpWebRequest)requestPropertyInfo.GetValue(request, null);

    // Setting KeepAlive 
    webRequest.KeepAlive = false;

    return request;
}

11 Comments

  • I've seen this happen when I call web services with proxy servers. We used the same approach mentioned above with the exception of changing the protocol version instead of setting keep-alives.



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

  • Thanks for the fix, it works great.



    I also have a question. Should you use this method only for web service calls that include WSE functionality or can you use it on all web service calls.



    P.S.

    I did see the example on how to fix the issue for non-WSE web services that link to this page...

  • another thing you might try...



    You can access the SoapHttpChannelOptions if you downcast (errr) the Channel property of the SoapSender/SoapClient to SoapHttpOutputChannel. SoapHttpChannelOptions has a KeepAlive property. At least that way you don't have to subclass.

  • I have added that method in Reference.cs, now I am having a different kind of problem, the request object credentials are not carried and I am getting "Unauthorized access" exception.

    Is there anything that I am missing.

  • You can also use this

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

    Dim w As Microsoft.Web.Services2.SoapWebRequest = MyBase.GetWebRequest(uri)
    Dim httpw As HttpWebRequest = w.Request
    httpw.KeepAlive = False
    httpw.ProtocolVersion = HttpVersion.Version10
    Return w

    End Function

  • Yep, still happens in ASP.Net 2.0 and WSE 2.0 and the security info is lost. At the top level webservice level, you can't get to the underlying connection that is used and overriding the getwebrequest method loses the security info :-P

  • Authorization can't work with KeepAlive set to false because it needs more than one roundtrip.
    Right ?

  • Hello,

    I'm trying this. However, i'm getting the following error inside this method.
    Object reference not set to an instance of an object.

    Anybody has any idea about this.

    Thanks

  • 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

  • Hi all, I'm using VS 2005 Framework 2.0 WSE 3.0. VS didn't add a class WebService\reference.cs, so I created a class called

    MyWebServiceSubClass

    and added the following code:


    using System;
    using System.Net;
    using System.Reflection;

    ///
    /// Summary description for subClassedWebService
    ///
    public class subClassedWebService:SessionManager.Service
    {
    public subClassedWebService()
    {
    //
    // TODO: Add constructor logic here
    //
    }

    private static PropertyInfo requestPropertyInfo = null;
    protected override WebRequest GetWebRequest(Uri uri)
    {

    if (requestPropertyInfo==null)
    // Retrieve property info and store it in a static member for optimizing future use
    requestPropertyInfo = request.GetType().GetProperty("Request");

    // Retrieve underlying web request
    HttpWebRequest webRequest =
    (HttpWebRequest)requestPropertyInfo.GetValue(request,null);

    // Setting KeepAlive
    webRequest.KeepAlive = false;
    return request;
    }

    }

    Bu I'm getting the exception:

    Object reference not set to an instance of an object.

    in the line:

    requestPropertyInfo = request.GetType().GetProperty("Request");

    Does somebody know why?

    Thanks in advance My email is ureyes84 at gmail.com

  • [url=http://groups.google.fr/group/cassotto6705/web/jeu-casino-virtuel]jeu casino virtuel[/url] jeu casino virtuel http://groups.google.fr/group/cassotto6705/web/jeu-casino-virtuel http://groups.google.fr/group/calvin8606/web/download-slot-machine [url=http://groups.google.fr/group/calvin8606/web/download-slot-machine]download slot machine[/url] download slot machine jeu sur internet [url=http://groups.google.fr/group/cassotto6705/web/jeu-sur-internet]jeu sur internet[/url] http://groups.google.fr/group/cassotto6705/web/jeu-sur-internet http://groups.google.fr/group/cassotto6705/web/play-slots-online [url=http://groups.google.fr/group/cassotto6705/web/play-slots-online]play slots online[/url] play slots online http://groups.yahoo.com/group/Loanpayday money tree payday loan [url=http://groups.yahoo.com/group/Loanpayday]loan payday[/url]

Comments have been disabled for this content.