在 .NET Core(以及后续的 .NET 5+)中,
ServicePointManager**完全不起作用**,所有对其属性(如
SecurityProtocol、
DefaultConnectionLimit、
ServerCertificateValidationCallback)的设置都会被忽略。
为什么 ServicePointManager 被移除了
.NET Core 从头重写了网络栈,不再基于旧版 .NET Framework 的
System.Net.ServicePoint模型。HTTP 客户端底层改用
HttpClientHandler(或其跨平台实现
SocketsHttpHandler),而
ServicePointManager是一个静态全局配置器,与现代依赖注入、实例化控制和跨平台设计原则冲突。
ServicePointManager在 .NET Core 中仍存在(为兼容性保留类型),但内部逻辑为空或直接返回默认值 调用
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12不会改变任何实际行为 设置
ServicePointManager.ServerCertificateValidationCallback对
HttpClient请求无效
替代方案:用 HttpClientHandler 配置 TLS 和证书验证
你需要显式构造
HttpClientHandler并传给
HttpClient,或通过 DI 注册自定义 handler。 TLS 协议版本由
HttpClientHandler.SslOptions.EnabledSslProtocols控制(.NET Core 2.1+) 证书验证回调应设在
HttpClientHandler.ServerCertificateCustomValidationCallback连接限制等参数需通过
SocketsHttpHandler(而非
ServicePoint)设置
var handler = new HttpClientHandler(); handler.SslOptions.EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13; handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => true; // 仅测试用 var client = new HttpClient(handler);
全局默认协议版本怎么设(比如强制 TLS 1.2)
不能靠
ServicePointManager,而是通过以下任一方式: 应用启动时调用
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true)(通常不需要,.NET Core 2.1+ 默认已启用)
在进程启动早期设置环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=1更可靠的做法:在创建每个
HttpClientHandler时明确指定
SslOptions.EnabledSslProtocols.NET 6+ 还支持通过
AppContext.SetSwitch("System.Net.Http.EnableMultipleHttp2Connections", true) 等开关微调,但 TLS 协议仍需 handler 级控制
最易踩的坑是:把 .NET Framework 项目里的
ServicePointManager设置原样复制到 .NET Core 中,结果 TLS 握手失败或证书验证静默绕过却毫无察觉 —— 因为那些代码根本没生效。
