前言:

  前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题。背景,关于调用第三方的接口都是使用使用自己封装的一个HttpWebRequestHepler帮助类,在本地开发时调用第三方接口都是正常的。然而当我部署到运维给我一个服务器(阿里云服务器)时刚开始提示是请求被中止: 未能创建 SSL/TLS 安全通道,之后经过一番修改以后就是提示基础连接已经关闭: 发送时发生错误。之后尝试了各种方法,还是没有办法解决基础连接已经关闭: 发送时发生错误这个问题。最后真的是无能为力,光这个问题找了一下午的解决方案,最后换到了我自己的阿里云服务器是可以正常调通第三方接口的。然后让运维看了下服务器结果是这个服务器都没有开通外网,所以导致了这个问题的出现。下面记录下问题排除的过程,希望能够帮助到遇到这种坑的小伙伴。

一、自己封装的一个通用的HttpWebRequestHepler Http Web网络请求帮助类:

    /// <summary>
/// Http Web网络请求帮助类
/// </summary>
public class HttpWebRequestHepler
{
private static HttpWebRequestHepler _httpWebRequestHepler;
private string _resContent;//响应内容
private string _errInfo;//错误信息
private int _responseCode;//响应状态码 public static HttpWebRequestHepler _
{
get => _httpWebRequestHepler ?? (_httpWebRequestHepler = new HttpWebRequestHepler());
set => _httpWebRequestHepler = value;
} /// <summary>
/// 数据请求
/// </summary>
/// <param name="requestUrl">请求地址</param>
/// <param name="postData">请求参数</param>
/// <param name="accessToken">授权token</param>
/// <param name="contentType">请求标头值类型</param>
/// <param name="method">请求方式</param>
/// <returns></returns>
public string HttpWebResponseData(string requestUrl, string postData, string accessToken = "", string contentType = "application/json", string method = "POST")
{
HttpWebResponse wr = null; try
{
var hp = (HttpWebRequest)WebRequest.Create(requestUrl);
hp.Timeout = 60 * 1000 * 10;//以毫秒为单位,设置等待超时10分钟
hp.Method = method;
hp.ContentType = contentType;
if (!string.IsNullOrWhiteSpace(accessToken))
{
hp.Headers.Add("Authorization", "Bearer " + accessToken);//增加headers请求头信息
} if (postData != "")//带参数请求
{
byte[] data = Encoding.UTF8.GetBytes(postData);
hp.ContentLength = data.Length;
Stream ws = hp.GetRequestStream(); // 发送数据
ws.Write(data, 0, data.Length);
ws.Close();
} wr = (HttpWebResponse)hp.GetResponse();
var sr = new StreamReader(wr.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8); this._resContent = sr.ReadToEnd();
sr.Close();
wr.Close();
}
catch (Exception exp)
{
this._errInfo += exp.Message;
if (wr != null)
{
this._responseCode = Convert.ToInt32(wr.StatusCode);
} return this._resContent;
} this._responseCode = Convert.ToInt32(wr.StatusCode); return this._resContent;
} }

二、请求被中止: 未能创建 SSL/TLS 安全通道问题解决:

  把项目部署到阿里云服务器中,请求第三方提示请求被中止: 未能创建 SSL/TLS 安全通道。首先字面上可以看出来这个https请求安全协议的问题。微软官方说明是,NET 4.6需要添加

ServicePointManager.SecurityProtocol属性,指定schnanel安全包支持的安全协议

微软官方解释:

此属性选择要用于新连接的安全套接字层 (SSL) 或传输层安全性 (TLS) 协议的版本;不会更改现有连接。

从 .NET Framework 4.7 开始,此属性的默认值为 SecurityProtocolType.SystemDefault 。 这允许基于 SslStream ((如 FTP、HTTP 和 SMTP) )的 .NET Framework 网络 api 从操作系统或系统管理员执行的任何自定义配置继承默认安全协议。 有关默认情况下在每个版本的 Windows 操作系统上启用了哪些 SSL/TLS 协议的信息,请参阅 TLS/SSL (SCHANNEL SSP) 中的协议

对于通过 .NET Framework 4.6.2 的 .NET Framework 版本,不会列出此属性的默认值。 安全环境不断变化,默认的协议和保护级别会随着时间的推移而更改,以避免已知的漏洞。 默认值因单独的计算机配置、已安装的软件和应用的修补程序而异。

解决方案:

//todo:指定请求包的安全协议,因为不知道你当前项目到底是哪个版本所以为了安全保障都加上
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

三、基础连接已经关闭: 发送时发生错误

这个问题查阅了网上几个比较典型的博客试了下,结果都没有办法解决我的问题,一下记录下这几个博客的解决方案,希望可以帮助到遇到这样问题的小伙伴。

1、一般来说添加了上面的ServicePointManager.SecurityProtocol属性就可以解决这个基础连接关闭的问题。

2、C# HttpRequest基础连接已经关闭: 接收时发生意外错误(原文地址):

//增加下面两个属性即可
hp.KeepAlive = false;
hp.ProtocolVersion = HttpVersion.Version10;

四、开启阿里云服务器外网(我的解决方案)

  查看一下你的服务器是否开通了外网,假如没有开通服务器外网在进行尝试。阿里云服务器配置外网访问参考。因为这个奇葩问题花费了一天宝贵的时间,考虑问题还是得多方面考虑。

.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决的更多相关文章

  1. 请求被中止: 未能创建 SSL/TLS 安全通道

    出现“请求被中止: 未能创建 SSL/TLS 安全通道.”的问题. 在创建请求地址的前面加了这句代码就可以了 System.Net.ServicePointManager.SecurityProtoc ...

  2. 请求被中止: 未能创建 SSL/TLS 安全通道,设置 TLSv1.2和TLSv1.1版本 .基础链接已经关闭,发送时发生错误

    WSO2 API访问的安全要求, 只能提供TLSv1.2和TLSv1.1版本,其它SSL版本协议因为存在较高安全漏洞问题会被disable. A 改成TLSv1.1或TLSv1.2,最好使用TLSv1 ...

  3. C# 请求被中止: 未能创建 SSL/TLS 安全通道。 设置SecurityProtocol无效

    今天为了获取一张图片,用了一段代码: ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateV ...

  4. 彻底解决:请求被中止: 未能创建 SSL/TLS 安全通道

    最近有个项目要调用客户用java写的带https的webservice,对方提供了证书文件 test.pfx,我这里调用方式如下: //webservice代理类 SvcService svc = n ...

  5. C# 解决“请求被中止: 未能创建 SSL/TLS 安全通道”的问题

    最近在开发项目的时候,使用爬虫抓取网络数据的时候,当请求Web数据时,碰到了“请求被中止: 未能创建 SSL/TLS 安全通道”的问题,尝试过很多网上的方法,例如添加证书等都没有用.最后在GitHub ...

  6. 请求被中止: 未能创建 SSL/TLS 安全通道,以及解决方法,即:Could not create SSL/TLS secure channel

    C# 访问https请求被中止: 未能创建 SSL/TLS 安全通道(Could not create SSL/TLS secure channel) 以及 X509Certificate2 temp ...

  7. C#使用HttpWebRequest 进行请求,提示 基础连接已经关闭: 发送时发生错误。

    本人今天遇到的错误,C#使用HttpWebRequest 进行请求,提示 基础连接已经关闭: 发送时发生错误. 测试了很久,才发现,是安全协议问题,把安全协议加上就可以了

  8. 【已解决】Https请求——基础连接已经关闭 发送时发生错误

    本人在做商用项目的推送消息功能时,借助第三方推送服务.这里避免有打广告的嫌疑,就不报名字了.由于是通过调用API接口,所以Post方法是自己写的,但是在开发环境是可以正常推送的,但是一上线就出各种问题 ...

  9. Paypal开发中遇到请求被中止: 未能创建 SSL/TLS 安全通道及解决方案

    最近在基于ASP.NET上开发了Paypal支付平台,在ASP.NET开发的过程中没有遇到这个问题,但是引用到MVC开发模式中的时候就出现了"未能创建 SSL/TLS 安全通道及解决方案&q ...

随机推荐

  1. CodeMirror动态修改代码(关键: editor.getDoc().setValue(data); editor.refresh();)

    在使用codemirror时,其原理是根据form中的textarea标签,自动加载其内容,获得代码行的显示.(具体使用方式参见 codemirror官网使用手册 http://codemirror. ...

  2. 从零开始搞后台管理系统(1)——shin-admin

      shin 的读音是[ʃɪn],谐音就是行,寓意可行的后台管理系统,shin-admin 的特点是: 站在巨人的肩膀上,依托Umi 2.Dva 2.Ant Design 3和React 16.8搭建 ...

  3. C#关于panle重叠

    当多个panle重叠不显示不出来的时候  选择视图---------------其它窗口----------------文档大纲  然后拖动进行调整

  4. 图解CyclicBarrier运动员接力赛

    图解游戏规则 大家都知道运动员短跑接力赛,今天我们并不是讲接力赛,我们讲"接力协作赛",需要我们重新定义下游戏规则:如下图所示 现在有运动员A,B,先定义游戏规则:赛道目前是300 ...

  5. Java练习——抽象类

    需求: 2辆宝马,1辆别克商务舱,1辆金龙(34)座,租5天共多少租金.   轿车 客车(金杯.金龙) 车型 别克商务舱GL8 宝马550i 别克林荫大道 <=16座 >16座 日租费(元 ...

  6. 日志文件迁移至OSS

    一台服务器在用阿里云ECS,因为穷,磁盘空间有限,服务器日志文件每天都在增长,需要定期清理释放磁盘空间,想到几种解决方案: 写任务定时备份到本地服务器 直接下载到本地用移动硬盘备份 备份到阿里云OSS ...

  7. STL中常用容器及操作 学习笔记1

    @[TOC](下面介绍STL中常见的容器及操作)## 不定长数组 vector> vetcor:其实就是一个数组或者说是容器 其操作不同于之前直接定义的数组 > 而且可以直接赋值也可以直接 ...

  8. Python Flask框架路由简单实现

    Python Flask框架路由的简单实现 也许你听说过Flask框架.也许你也使用过,也使用的非常好.但是当你在浏览器上输入一串路由地址,跳转至你所写的页面,在Flask中是怎样实现的,你是否感到好 ...

  9. ubantu16与windows下——redis的安装与使用

      (1) 打开ubantu16,使用如下命令下载安装包 wget http://download.redis.io/releases/redis-2.8.3.tar.gz (2)解压缩命令: tar ...

  10. Go语言学习笔记——Go语言的指针

    Go具有指针.指针保存了变量的内存地址. 类型*T是指向类型T的值得指针.其零值是nil var p *int &符号会生成一个指向其作用对象的指针 i:=42 P=&i *符号表示指 ...