net 5.0 无法确定帧大小或接收到损坏的帧

net 5.0 Cannot determine the frame size or a corrupted frame was received

我想试试 net5.0,因为它在 rc2 中,我遇到了一个奇怪的问题。

我已经在 net5.0 中创建了一个默认的 WebApi。我没有触摸任何东西,我只是点击了 运行(在 kestrel 中,而不是 ISS),Swagger 主页出现了。我尝试了 WeatherForcast get,一切正常。

然后我在 NET5.0 中创建了一个控制台应用程序并添加了这段代码:

static async Task Main(string[] args)
{
    var clientHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (_, _, _, _) => true
    };
    var client = new HttpClient(clientHandler);
    try
    {
        var httpMessage = await client.GetAsync("https://localhost:5001/WeatherForecast");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

使用这段代码我得到了以下错误:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.IO.IOException: Cannot determine the frame size or a corrupted frame was received.

在那之后,我在 Postman 上尝试了同样的请求并且它成功了(因为 swagger)。 我的最终测试是将控制台应用程序切换到 netcore 3.1 并且请求有效。

所以我只在 net5.0 应用程序上遇到此错误。

有什么建议吗?

编辑:

Kestrel 用于强制选择 Tls 1.1 或 Tls 1.2。从 .Net 5.0 Preview 6 开始,它被更改为“None”,意思是 OS 默认值。 Kestrel Default Tls Support

巧合的是,Microsoft 去年开始在 Windows 10 中默认启用 Tls 1.3。Windows 10 Tls 1.3 Enabled by Default因此您的应用程序现在可能正在使用我发现有时“有问题”的 Tls 1.3。

要将 Tls 1.3 设置为默认禁用(意味着可用于请求它的应用程序,否则关闭),在您的注册表中转到或创建此路径:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client

并设置或创建一个名为 DisabledByDefault 的 DWORD 到 1

这应该使您的浏览器支持 Tls 1.2。

对于您的 Kestrel 服务器,类似地:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server

此外,设置或创建一个名为 DisabledByDefault 的 DWORD 到 1

如果不这样做,在客户端和服务器下也创建一个名为“已启用”的 DWORD 设置为 0。这将完全禁用 Tls 1.3。

我知道这是一个老问题,但我遇到了它,并通过在 api url 部分将“https”更改为“http”解决了这个问题。

在这个问题中会发生变化:

var httpMessage = await client.GetAsync("https://localhost:5001/WeatherForecast");

收件人:

var httpMessage = await client.GetAsync("http://localhost:5001/WeatherForecast");