You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将使用WebRequestHandler的代码迁移至.NET Standard 2.0适配问题

可行解决方案

你可以根据项目实际情况选择以下任意一种方案,不需要迁移到.NET Core 2.1,也不会影响现有.NET Framework 4.8程序的依赖。

方案1:多目标框架(推荐,零行为差异)

这是兼容性最好的方案,不需要改写原有业务逻辑,只需要修改类库的项目配置,让它同时针对net48和netstandard2.0两个目标框架编译:

  • 右键项目编辑csproj文件,将原本的单目标配置修改为多目标配置:
<TargetFrameworks>net48;netstandard2.0</TargetFrameworks>
  • 用条件编译符号拆分不同目标框架下的Handler初始化逻辑,.NET Framework 4.8编译时继续沿用原有WebRequestHandler逻辑,.NET Standard 2.0编译时用兼容实现,示例代码如下:
private static HttpClient CreateHttpClientItem(Uri uri, TimeSpan timeout, HttpMessageHandler messageHandler)
{
    if (messageHandler == null)
    {
#if NET48
        messageHandler = new WebRequestHandler
        {
            Credentials = new CredentialCache
            {
                { uri, "NTLM", CredentialCache.DefaultNetworkCredentials }
            },
            AllowAutoRedirect = true,
            UnsafeAuthenticatedConnectionSharing = true
        };
#else
        // .NET Standard 2.0下用WinHttpHandler,行为和WebRequestHandler高度一致
        messageHandler = new WinHttpHandler
        {
            Credentials = new CredentialCache
            {
                { uri, "NTLM", CredentialCache.DefaultNetworkCredentials }
            },
            AllowAutoRedirect = true,
            UnsafeAuthenticatedConnectionSharing = true,
            // 配置连接池参数,从根源避免TIME_WAIT端口堆积
            MaxConnectionsPerServer = 10,
            TcpKeepAliveEnabled = true,
            TcpKeepAliveTime = TimeSpan.FromMinutes(5)
        };
#endif
    }

    return new HttpClient(messageHandler)
    {
        BaseAddress = uri,
        Timeout = timeout
    };
}
  • 给netstandard2.0的目标框架添加System.Net.Http.WinHttpHandler的NuGet包引用,用条件引用避免net48下引入多余依赖:
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
  <PackageReference Include="System.Net.Http.WinHttpHandler" Version="7.0.0" />
</ItemGroup>

该方案下,原有依赖类库的.NET Framework 4.8程序引用的是net48版本的编译输出,完全沿用之前的逻辑,不会有任何行为变化;需要.NET Standard 2.0版本的引用方拿到的是对应编译输出,也能正常使用NTLM认证、连接复用能力。

方案2:单目标.NET Standard 2.0,直接替换为WinHttpHandler

如果不想做多目标编译,可以直接把项目目标保持为netstandard2.0,移除.NET Framework专属的WebRequestHandler相关引用,安装System.Net.Http.WinHttpHandlerNuGet包,直接用方案1中#else块的WinHttpHandler初始化逻辑替换原来的WebRequestHandler即可。
WinHttpHandler是微软官方提供的HTTP消息实现,底层基于Windows WinHTTP接口(和WebRequestHandler底层同源),完全支持NTLM默认认证、自动重定向、非安全认证连接共享等特性,同时暴露了完整的连接池配置参数,只要正确设置MaxConnectionsPerServer、开启TCP KeepAlive,就不会出现静态HttpClient产生大量TIME_WAIT端口的问题。

方案3:原生HttpClientHandler兼容配置(无额外依赖)

如果不想引入额外的NuGet包,也可以用.NET Standard 2.0自带的HttpClientHandler,手动补齐对应的属性配置和连接池参数,也能达到同样效果:

messageHandler = new HttpClientHandler
{
    Credentials = new CredentialCache
    {
        { uri, "NTLM", CredentialCache.DefaultNetworkCredentials }
    },
    AllowAutoRedirect = true,
    UnsafeAuthenticatedConnectionSharing = true,
    MaxConnectionsPerServer = 10,
    UseProxy = false, // 根据实际代理需求配置
    UseDefaultCredentials = false
};

该方案下必须确保HttpClient实例是长生命周期(静态/单例),不要每次请求都新建HttpClient实例,同时MaxConnectionsPerServer不要设置为int.MaxValue,就能避免TIME_WAIT端口堆积问题。

注意:无论选择哪种方案,都不要在每次HTTP请求时新建HttpClient和对应的HttpMessageHandler,应该将初始化好的HttpClient实例缓存起来复用,这是避免TIME_WAIT端口问题的核心前提。

内容的提问来源于stack exchange,提问作者Marcin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:24:34