访问https接口报错 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系

详细错误信息如下

请求错误信息:发生一个或多个错误。System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。 ---> System.Security.Authentication.AuthenticationException: 根据验证过程,远程证书无效。
在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- 内部异常堆栈跟踪的结尾 ---
在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
在 System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- 内部异常堆栈跟踪的结尾 ---

 

原本这个接口是http协议的,后来第三方为了安全使用了https协议😳

致使我的方法不支持https访问而报错🤔

 

我原本的调用方法如下

        public static string Post(string httpUrl, string requestJson, ref List<string[]> msg, string source)
        {
            string strRet = string.Empty;
            int doop = 1;
            HttpResponseMessage response = new HttpResponseMessage();
            do
            {
                if (doop != 1)
                    Thread.Sleep(60000);
                try
                {
                    using (var client = new HttpClient())
                    {
                        HttpContent httpContent = new StringContent(requestJson);
                        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                        response = client.PostAsync(httpUrl, httpContent).Result;
                        if (response.IsSuccessStatusCode)
                        {
                            strRet = response.Content.ReadAsStringAsync().Result;
                            msg.Add(new string[] { "Success", "post 发送的第" + doop + "次请求数据[" + httpUrl + "],[" + requestJson + "]" });
                        }
                        else
                        {
                            msg.Add(new string[] { "Error","post 的第" + doop + "次请求失败,数据[" + httpUrl + "],[" + requestJson + "]" + "\n"
                            + "请求错误信息:" + response.ReasonPhrase });
                        }
                    }
                }
                catch (Exception ex)
                {
                    strRet = string.Empty;
                    msg.Add(new string[] { "Error","post 发送的第" + doop + "次请求数据[" + httpUrl + "],[" + requestJson + "]" + "\n"
                        + "请求错误信息:" + ex.Message + ex.InnerException });
                }
                doop++;
            }
            while (doop <= 10 && !response.IsSuccessStatusCode);
            return strRet;
        }
View Code

 

在网上查阅了资料找到了解决方案,大致如下

调用http访问前写这句话
ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();  

internal class AcceptAllCertificatePolicy : ICertificatePolicy
    {
        public AcceptAllCertificatePolicy()
        {
        }

        public bool CheckValidationResult(ServicePoint sPoint,
           X509Certificate cert, WebRequest wRequest, int certProb)
        {
            // Always accept
            return true;
        }
    }

这么写有点麻烦,但是能解决问题

查看了ServerCertificateValidationCallback属性,发现它的类型为RemoteCertificateValidationCallback的委托,为何不直接写一个参数相同的方法直接返回true呢

 public delegate bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors);

 

解决方案

   ServicePointManager.ServerCertificateValidationCallback = Callback;

        private static bool Callback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

 

最终我的代码如下

        public static string Post(string httpUrl, string requestJson, ref List<string[]> msg, string source)
        {
            string strRet = string.Empty;
            int doop = 1;
            HttpResponseMessage response = new HttpResponseMessage();
            do
            {
                if (doop != 1)
                    Thread.Sleep(60000);
                try
                {
                    using (var client = new HttpClient())
                    {
                        ServicePointManager.ServerCertificateValidationCallback = Callback;
                        HttpContent httpContent = new StringContent(requestJson);
                        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                        response = client.PostAsync(httpUrl, httpContent).Result;
                        if (response.IsSuccessStatusCode)
                        {
                            strRet = response.Content.ReadAsStringAsync().Result;
                            msg.Add(new string[] { "Success", "post 发送的第" + doop + "次请求数据[" + httpUrl + "],[" + requestJson + "]" });
                        }
                        else
                        {
                            msg.Add(new string[] { "Error","post 的第" + doop + "次请求失败,数据[" + httpUrl + "],[" + requestJson + "]" + "\n"
                            + "请求错误信息:" + response.ReasonPhrase });
                        }
                    }
                }
                catch (Exception ex)
                {
                    strRet = string.Empty;
                    msg.Add(new string[] { "Error","post 发送的第" + doop + "次请求数据[" + httpUrl + "],[" + requestJson + "]" + "\n"
                        + "请求错误信息:" + ex.Message + ex.InnerException });
                }
                doop++;
            }
            while (doop <= 10 && !response.IsSuccessStatusCode);
            return strRet;
        }
        private static bool Callback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

 

posted @ 2019-05-15 16:14  听雨的人  阅读(7333)  评论(2编辑  收藏  举报