Search code examples
c#xmlwebclientxmldocumentups

C# WebClient Exception: The underlying connection was closed


i am sending xml data to UPS web site, some time i am getting response and some time i am getting the Exception: The underlying connection was closed

see a sample code which send xml to a specific UPS url.

    public ShippingAcceptResult ShippingAccept(string acceptDigestCode)
    {
    string strXml = "";
    try
    {
        xmlRequest = new System.Xml.XmlDocument();
        xmlRequest.LoadXml(@"<?xml version=""1.0""?>
     <ShipmentAcceptRequest>
       <Request>
          <TransactionReference>
         <CustomerContext>TR01</CustomerContext>
         <XpciVersion>1.0001</XpciVersion>
          </TransactionReference>
          <RequestAction>ShipAccept</RequestAction>
          <RequestOption>01</RequestOption>
       </Request>
       <ShipmentDigest>" + acceptDigestCode + "</ShipmentDigest></ShipmentAcceptRequest>");

        byte[] bb = new System.Text.ASCIIEncoding().GetBytes(string.Format(XML_CONNECT, sAccessCode.Trim(), sUserId.Trim(), sPassword.Trim()));
        byte[] bResponse = null; 
        System.IO.MemoryStream ms = new System.IO.MemoryStream();
        ms.Write(bb, 0, bb.Length);
        xmlRequest.Save(ms);
        bb = ms.ToArray();
        xmlRespone = new XmlDocument();
        string serverName = (testMode) ? "wwwcie" : "onlinetools.ups.com";
        serverName = string.Format(UPS_SERVICE_URL, serverName, ShipRequestTypes.ShipAccept);

        using (var client = new NoKeepAlivesWebClient())
        {
        bResponse = client.UploadData(serverName, "POST", bb);
        }

        if (bResponse != null)
        {
        xmlRespone.LoadXml(System.Text.ASCIIEncoding.ASCII.GetString(bResponse));
        }
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show("ShippingAccept " + ex.Message);
        System.Windows.Forms.MessageBox.Show(strXml);
    }
    return new ShippingAcceptResult(xmlRespone);

}

public class NoKeepAlivesWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
        ((HttpWebRequest)request).KeepAlive = false;
        }

        return request;
    }
}

before i did not set KeepAlive = false then also i was getting same error message but now when i set KeepAlive = false then also some time getting the same connection close related error.

tell me the error is specific to any pc?

should i set timeout value for webclient like KeepAlive option?

so please someone drive me to right direction to get rid of this error.

tell me all possible reason for which error is occurring. thanks


Solution

  • actually these line of code solve my issue

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; //768 for TLS 1.1 and 3072 for TLS 1.2
    //ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
    //System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    

    few more code snippet i used along with ServicePointManager

    using (var client = new NoKeepAlivesWebClient())
    {
        bResponse = client.UploadData(serverName, "POST", bb);
    }
    
    /// Certificate validation callback.
    /// </summary>
    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        // If the certificate is a valid, signed certificate, return true.
        if (error == System.Net.Security.SslPolicyErrors.None)
        {
        return true;
        }
    
        Console.WriteLine("X509Certificate [{0}] Policy Error: '{1}'",
        cert.Subject,
        error.ToString());
    
        return false;
    }
    
    public class NoKeepAlivesWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
            ((HttpWebRequest)request).KeepAlive = false;
            ((HttpWebRequest)request).Timeout = 60000;
            }
    
            return request;
        }
    }