简体   繁体   English

HttpClient HttpRequestMessage 在 net6 中失败,但在 net4.8 中有效

[英]HttpClient HttpRequestMessage fails in net6 but works in net4.8

I have two different projects, one written in.Net 4.8 and another in.Net6.我有两个不同的项目,一个用.Net 4.8 编写,另一个用.Net6 编写。

The code works fine in .net 4.8, but fails in .net6.该代码在 .net 4.8 中运行良好,但在 .net6 中失败。 The exceptions I get, and it's inner exceptions, is我得到的异常,它是内部异常,是

The SSL connection could not be established, see inner exception无法建立 SSL 连接,请参阅内部异常

Authentication failed, see inner exception身份验证失败,请参阅内部异常

The token supplied to the function is invalid提供给 function 的令牌无效

The code is written in the same way, no difference at all.代码是用同样的方式写的,完全没有区别。 First the part for the System.Net.Http.HttpClient _httpRequestClient:首先是 System.Net.Http.HttpClient _httpRequestClient 的部分:

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
        string baseAddress = host;

        string credentials = Convert.ToBase64String(new ASCIIEncoding().GetBytes(string.Format("{0}:{1}", connection.Username, connection.Password)));


        _httpRequestClient = new HttpClient();
        _httpRequestClient.BaseAddress = new Uri(baseAddress);
        _httpRequestClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("basic",
                 credentials);

        _httpRequestClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

And when making a call to the server from an async Task it throws the exeption:当从异步任务调用服务器时,它会抛出异常:

using (var response = await _httpRequestClient.SendAsync(
                    new HttpRequestMessage(HttpMethod.Get, command), HttpCompletionOption.ResponseHeadersRead)
                    )

While debugging, the _httpRequestClient.DefaultRequestHeaders.Authorization is exactly the same in both projects (as well as most of the values) except that in .net6 the _httpRequestClient also has DefaultRequestVersion and DefaultVersionPolicy.调试时,两个项目中的 _httpRequestClient.DefaultRequestHeaders.Authorization 完全相同(以及大多数值),除了在 .net6 中 _httpRequestClient 还具有 DefaultRequestVersion 和 DefaultVersionPolicy。

For now at least, I really cannot figure out what's wrong.至少现在,我真的不知道出了什么问题。 Please help:)请帮忙:)

First of, thanks for pointing me to the right direction.首先,感谢您为我指出正确的方向。

However, .Net framework and.Net standard has some differences.但是,.Net 框架和.Net 标准有一些区别。

In .net standard, the following code doesn't seem to do anything in my usage:在 .net 标准中,以下代码在我的使用中似乎没有任何作用:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

Instead, I had to create an instance of HttpClientHandler and pass it to the HttpClient constructor.相反,我必须创建一个 HttpClientHandler 实例并将其传递给 HttpClient 构造函数。 See below:见下文:

        _httpClientHandler = new HttpClientHandler();
        _httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
        _httpClientHandler.ServerCertificateCustomValidationCallback =
            (httpRequestMessage, cert, cetChain, policyErrors) =>
            {
                //TODO Add custom validation
                return true;
            };


        string credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{connection.Username}:{connection.Password}"));

        //Added _httpClientHandler to constructor
        _httpRequestClient = new HttpClient(_httpClientHandler);
        _httpRequestClient.BaseAddress = new Uri(baseAddress);
        _httpRequestClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("basic",
                 credentials);

        _httpRequestClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

The final, and main hint to what was wrong, was found here: https://stackoverflow.com/a/46626858/2488982在这里找到了错误的最终和主要提示: https://stackoverflow.com/a/46626858/2488982

Again, thank everyone:)再次感谢大家:)

Edit: Certificate validation should not be tampered with.编辑:证书验证不应被篡改。 If self signed certificates are to be used, add them to trusted CA for the clients.如果要使用自签名证书,请将它们添加到客户端的受信任 CA。

This means my code has been reduced to this:这意味着我的代码已简化为:

string credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{connection.Username}:{connection.Password}"));


        _httpRequestClient = new HttpClient();
        _httpRequestClient.BaseAddress = new Uri(baseAddress);
        _httpRequestClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("basic",
                 credentials);

        _httpRequestClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        _httpRequestClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
        _httpRequestClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/vnd.assaabloy.arx.integrated-alarm-1.0+json"));

No custom validation is done anymore.不再进行自定义验证。

Thanks Panagiotis Kanavos for your input.感谢 Panagiotis Kanavos 的意见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM