訪問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;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM