详细错误信息如下
请求错误信息:发生一个或多个错误。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;
}
在网上查阅了资料找到了解决方案,大致如下
调用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;
}
来源:oschina
链接:https://my.oschina.net/u/4261593/blog/3536661