訪問https接口報錯 基礎鏈接已經關閉: 未能爲 SSL/TLS 安全通道創建信任關係

詳細錯誤信息以下json

請求錯誤信息:發生一個或多個錯誤。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協議😳app

導致個人方法不支持https訪問而報錯🤔async

 

我本來的調用方法以下ide

        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

 

在網上查閱了資料找到了解決方案,大體以下oop

調用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;
        }
    }

這麼寫有點麻煩,可是能解決問題post

查看了ServerCertificateValidationCallback屬性,發現它的類型爲RemoteCertificateValidationCallback的委託,爲什麼不直接寫一個參數相同的方法直接返回true呢spa

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

 

解決方案code

   ServicePointManager.ServerCertificateValidationCallback = Callback;

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

 

最終個人代碼以下blog

        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;
        }
相關文章
相關標籤/搜索