背景:
(对方公司)提供接口服务,地址是http前缀的,加上用户名和密码等数据后测试时没有问题,可以直接调通,但在切换到生产后,地址变更为https前缀,然后这个接口就调不到。
产生问题分析:
https前缀会有ssl证书验证,在post调取该地址时,可以忽略掉该验证,否则会产生调不到的情况。
解决办法:
C#:
第一种办法:代码调用时需在调用地址前加忽略掉ssl验证这段代码,如下:

ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

整块代码如下:

public static string Post(string PostUrl, string Parameters)
        {
            string content = string.Empty;
            try
            {

                //转换为字节数组
                byte[] bytesRequestData = Encoding.UTF8.GetBytes(Parameters);
                //跳过ssl验证
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                //path不是登录界面,是登录界面向服务器提交数据的界面
                HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(PostUrl);
                myReq.Method = "post";
                myReq.ContentType = "application/json; charset=UTF-8";            
                myReq.Headers.Add("用户名", "####");
                myReq.Headers.Add("密码", "###");
                //填充POST数据
                myReq.ContentLength = bytesRequestData.Length;
                Stream requestStream = myReq.GetRequestStream();
                requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
                requestStream.Close();
                //发送POST数据请求服务器
                HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                //获取服务器返回信息
                Stream myStream = HttpWResp.GetResponseStream();
                StreamReader reader = new StreamReader(myStream, Encoding.UTF8);
                content = reader.ReadToEnd();
                reader.Close();
                HttpWResp.Close();
            }
            catch (Exception ex)
            {
                content = ex.ToString();
            }
            return content;
        }

第二种办法:

post接口时添加ssl证书:

//Certificates
                X509Certificate2 x509Certificate2 = new X509Certificate2("C:\\Users\\linpa\\Desktop\\预生产证书认证导入教程\\cnooctrm.pem");
                myReq.ClientCertificates.Add(x509Certificate2);
                
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);

上述为该模块的主要代码,完整代码如下:

#region POST提交参数
        /// <summary>
        /// POST提交参数
        /// </summary>
        /// <param name="PostUrl">POST的地址,需要传送的地址</param>
        /// <param name="Parameters">POST提交参数,例如“client_id=2866517568&client_secret=9c”和get的链接类似</param>
        /// <returns></returns>
        public static string Post(string PostUrl, string Parameters)
        {
            string content = string.Empty;
            try
            {
                //转换为字节数组
                byte[] bytesRequestData = Encoding.UTF8.GetBytes(Parameters);
                //path不是登录界面,是登录界面向服务器提交数据的界面
                HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(PostUrl);
                myReq.Method = "post";
                myReq.ContentType = "application/json; charset=UTF-8";
               myReq.Headers.Add("用户名", "####");
                myReq.Headers.Add("密码", "###");
                
                //Certificates
                X509Certificate2 x509Certificate2 = new X509Certificate2("C:\\Users\\linpa\\Desktop\\预生产证书认证导入教程\\cnooctrm.pem");
                myReq.ClientCertificates.Add(x509Certificate2);
                
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                //myReq.ProtocolVersion = HttpVersion.Version10;
                //DefaultConnectionLimit是默认的2,而当前的Http的connection用完了,导致后续的GetResponse或GetRequestStream超时死掉
                
                #region 如果报超时的错,可以把这两个注释去掉试一下
                //DefaultConnectionLimit是默认的2,而当前的Http的connection用完了,导致后续的GetResponse或GetRequestStream超时死掉
                //System.Net.ServicePointManager.DefaultConnectionLimit = 200;
                //myReq.Timeout = 5 * 60 * 1000;//ms
                #endregion 
                
                //填充POST数据
                myReq.ContentLength = bytesRequestData.Length;
                Stream requestStream = myReq.GetRequestStream();
                requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
                requestStream.Close();
                //发送POST数据请求服务器
                HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                //获取服务器返回信息
                Stream myStream = HttpWResp.GetResponseStream();
                StreamReader reader = new StreamReader(myStream, Encoding.UTF8);
                content = reader.ReadToEnd();
                reader.Close();
                HttpWResp.Close();
            }
            catch (Exception ex)
            {
                content = ex.ToString();
            }
            return content;
        }

        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {   // 总是接受  
            return true;
        }
        #endregion

以上为接口post https的两种解决办法,仅供参考,欢迎留言讨论!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐