.NET Framework 4.5环境下能否通过HTTP2发送API请求?
结论
.NET Framework 4.5 原生的HTTP栈(包括官方最新版System.Net.Http 4.3.4包)本身不支持HTTP/2,WinHttpHandler最低仅支持.NET Framework 4.6.1,所以无法通过原生HttpClient直接实现需求,但可以通过以下3种方案落地:
具体可行方案
方案1:本地反向代理协议转换(改造成本最低)
在你的服务所在服务器部署轻量反向代理(如Nginx),由代理完成HTTP 1.1到HTTP/2的转换:
- 现有.NET代码无需大幅修改,仅需把请求目标改为本地代理的监听地址,继续用HTTP 1.1发送请求即可
- Nginx侧配置示例:
server { listen 127.0.0.1:8080; location / { # 第三方API地址 proxy_pass https://第三方API域名/; # 开启HTTP/2转发 proxy_http_version 2.0; proxy_set_header Connection ""; # 按需配置SSL验证、超时等参数 } }
该方案仅需服务器允许部署Nginx,无需修改业务逻辑,稳定性最高
方案2:使用基于libcurl的第三方HTTP客户端
libcurl本身原生支持HTTP/2,社区有多个.NET封装可以直接在.NET Framework 4.5中使用,比如LibCurl.NET、CurlSharp:
- 无需依赖.NET Framework原生HTTP栈,可直接指定使用HTTP/2协议发送请求
- 打包时需要携带对应架构的libcurl及其依赖的nghttp2、SSL库二进制文件
- 示例代码片段:
using CurlSharp; // 初始化curl Curl.GlobalInit(CurlInitFlag.All); using (var easy = new CurlEasy()) { easy.Url = apiURL; easy.Post = true; // 开启HTTP/2支持 easy.HttpVersion = CurlHttpVersion.Http2_0; // 填写POST表单数据 easy.PostFields = FormDataToString(data); easy.PostFieldSize = easy.PostFields.Length; // 接收返回值 string response = ""; easy.WriteFunction = (buf, size, nmemb, data) => { response += System.Text.Encoding.UTF8.GetString(buf, 0, size * nmemb); return (IntPtr)(size * nmemb); }; easy.Perform(); } Curl.GlobalCleanup();
方案3:P/Invoke调用原生WinHTTP API
Windows 10 1607、Windows Server 2016及以上版本的系统自带WinHTTP原生支持HTTP/2,可通过P/Invoke直接调用系统接口绕过.NET栈限制:
- 无需引入第三方依赖,仅需自己封装WinHTTP调用逻辑
- 要求服务运行的操作系统版本不能低于Win10 1607/Server 2016,老版本系统WinHTTP不支持HTTP/2
原代码报错原因
你当前遇到的Only HTTP/1.0 and HTTP/1.1 version requests are currently supported异常是.NET Framework 4.5的System.Net.Http底层实现的硬限制,该版本的.NET HTTP栈没有实现HTTP/2的编码、传输逻辑,即使手动设置HttpRequestMessage.Version = 2.0也无法生效。WinHttpHandler包的最低依赖为.NET Framework 4.6.1,因此无法在4.5版本项目中安装。
内容的提问来源于stack exchange,提问作者Mead Umandal

