.NET 2.1的核心配备了极大的改善上System.Net.HttpClient
对于 HttpClient,我们从头开始构建了一个新的托管 HttpClientHandler,称为SocketHttpHandler。正如您可能猜到的,它是基于 .NET 套接字和 Span 的 HttpClient 的 C# 实现。
我的应用程序是作为 Windows 服务托管的 ASP.NET Core 应用程序,根据 Microsoft这个文档,该项目是基于 .NET Core 但它TargetFramework是 .NET 框架。
该应用程序适用于面向 .NET 框架 4.7.1 的 .NET Core 2.0。
最近微软发布了 Microsoft.AspNetCore 2.1.0-rc1-final ,它可以用于生产。所以我尝试升级到这个版本。
所以我升级TargetFramework到 4.7.2 并升级参考如下。
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.WindowsServices" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.1.0-rc1-final" />
然后它停止工作并且编译器引发错误,例如找不到类型或命名空间名称“HttpClient”
我知道NuGet …
system.net dotnet-httpclient .net-core asp.net-core asp.net-core-2.0
在等待新的闪亮HttpClientFactory解决所有问题的同时HttpClient,
我仍然无法找到是否HttpResponseMessage和HttpRequestMessage应该处置的答案。
像下面这样的东西是一种很好的做法吗?
您是否使用 Using 语句HttpResponseMessage?
//httpClient has been injected
using (HttpResponseMessage messageResponse = await httpClient.GetAsync(uri, cancellationToken).ConfigureAwait(false))
{
using (HttpContent content = messageResponse.Content)
{
if (messageResponse.IsSuccessStatusCode)
{
var json = await content.ReadAsStringAsync();
var response = await Task.Run(() => JsonConvert.DeserializeObject<TResponse>(json, serializerSettings));
return new MyWrapperResponse<TResponse>(messageResponse,response);
}
}
}
Run Code Online (Sandbox Code Playgroud) 旧代码:
Client = new HttpClient(new HttpClientHandler() { DefaultProxyCredentials = CredentialCache.DefaultNetworkCredentials });
// set an default user agent string, some services does not allow emtpy user agents
if (!Client.DefaultRequestHeaders.Contains("User-Agent"))
Client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0");
Run Code Online (Sandbox Code Playgroud)
尝试使用新的 ASP.NET Core 2.1 HttpClientFactory 实现相同的功能:
services.AddHttpClient("Default", client =>
{
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
}).ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler() { DefaultProxyCredentials = CredentialCache.DefaultNetworkCredentials });
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到一个 HTTP 407(代理身份验证)错误。我做错了什么?
asp.net dotnet-httpclient .net-core asp.net-core httpclientfactory
所以我们大多数人可能已经读过我们应该重用 的实例,HttpClient而不是使用using和创建新的实例。这意味着我可以只HttpClient在我的程序中创建一个实例,并GetAsync使用每个请求的完整 uri 字符串进行调用。这使我的BaseAddress财产HttpClient。考虑以下代码:
HttpClient microsoftClient = new HttpClient() { BaseAddress = new Uri("https://www.microsoft.com/") };
HttpClient stackoverflowClient = new HttpClient() { BaseAddress = new Uri("https://stackoverflow.com/") };
var response = microsoftClient.GetAsync("about").Result;
Console.WriteLine($"I {((response.IsSuccessStatusCode) ? "can" : "cannot")} access microsoft.com/about from the microsoft client");
response = microsoftClient.GetAsync("trademarks").Result;
Console.WriteLine($"I {((response.IsSuccessStatusCode) ? "can" : "cannot")} access microsoft.com/trademarks from the microsoft client");
response = stackoverflowClient.GetAsync("company/about").Result;
Console.WriteLine($"I {((response.IsSuccessStatusCode) ? "can" : "cannot")} access stackoverflow.com/company/about …Run Code Online (Sandbox Code Playgroud) 我正在尝试从我们的 API 实例中获取数据。我拥有的代码几乎是复制了 MS 网站,并在 SO 上找到了柚木。我正在使用的代码是这样的:
string peopleEndpoint = $"{apiConf.ApiEndpoint}/{apiConf.dbspec}/_table/mdm.PEOPLE_SV";
string json = null;
try
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("X-Api-Key", apiConf.ApiKey);
HttpResponseMessage response = await httpClient.GetAsync(peopleEndpoint);
json = await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
throw;
}
Run Code Online (Sandbox Code Playgroud)
配置值很好...我可以将它们复制并粘贴到 cURL 命令中并获取数据。与标题相同。
现在,当我调试时,执行此行后停止执行:
HttpResponseMessage response = await httpClient.GetAsync(peopleEndpoint);
Run Code Online (Sandbox Code Playgroud)
而且,在输出窗口中,我看到的是:
The program '[10172] dotnet.exe' has exited with code 0 (0x0).
The program '[10172] dotnet.exe: Program Trace' has exited with code 0 (0x0).
Run Code Online (Sandbox Code Playgroud)
我如何找出导致此失败的原因?
该框架记为: …
我们System.Net.Http.HttpClient用于 k8s 内部微服务之间的调用。
几天前,我们注意到 http 调用的非常奇怪的行为:微服务之间的某些调用(接近 2-3%)因错误而失败
System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at OurCode.HttpServiceClient.GetStringResponseAsync(String methodUri, HttpMethod httpMethod)
...another our code...
Run Code Online (Sandbox Code Playgroud)
在我们的 http 调用超时后(3 秒)。但是没有关于被叫服务内部调用的日志。
我们启用了 packetbeat 来跟踪 http 请求,并且还注意到,没有任何从调用方服务到被调用方服务的 http 请求被执行。此服务的 CPU、内存和网络一直正常。
我们用于 http 调用的代码的简化版本如下所示:
public async Task<string> GetStringResponseAsync(String methodUri, HttpMethod httpMethod)
{
int timeoutInMilliseconds = 3000;
var tokenSource = new CancellationTokenSource();
var rm = new …Run Code Online (Sandbox Code Playgroud) 为什么我的 HttpClient 实例不会使用我提供的客户端证书进行相互身份验证?
我正在使用 HttpClient 进行双向 TLS。作为客户端,我将客户端证书添加到 WebRequestHandler,然后在新的 HttpClient 中使用该处理程序。
我的机器上没有安装证书。我已经成功地将它加载到处理程序中,并且在调试时可以看到它(密码也是正确的)。
我正在针对几个不同的测试域进行测试
两个测试应用程序都显示没有发送证书。
var clientCert = new X509Certificate2("badssl.pem", "badssl.com");
var webHandler = new WebRequestHandler();
webHandler.ClientCertificates.Add(clientCert);
var httpClient = new HttpClient(webHandler);
var result = await (await httpClient.GetAsync(uri)).Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 C# 和 HttpClient 类在 Spotify 登录页面上获取 cookie。但是,当我知道正在设置 cookie 时,CookieContainer 始终为空。我没有发送任何标头,但它仍然应该给我 cookie(s) 因为当我发送一个没有任何标头的 GET 请求时,我得到了 csrf 令牌。这是我的代码:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
using System.Web;
class Program
{
static void Main()
{
Task t = new Task(MakeRequest);
t.Start();
Console.WriteLine("Getting cookies!");
Console.ReadLine();
}
static async void MakeRequest()
{
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
Uri uri = new Uri("https://accounts.spotify.com/en/login/?_locale=en-US&continue=https:%2F%2Fwww.spotify.com%2Fus%2Faccount%2Foverview%2F");
HttpClient client = new HttpClient(handler); …Run Code Online (Sandbox Code Playgroud) 的建议HttpClient是重用单个实例。但是从 API 来看,添加证书的方式似乎是在实例上,而不是每个请求。例如,如果我们添加两个证书,我们如何确保“cert 1”仅发送到“one.somedomain.com”?
//A handler is how you add client certs (is there any other way?)
var _clientHandler = new HttpClientHandler();
//Add multiple certs
_clientHandler.ClientCertificates.Add(cert1);
_clientHandler.ClientCertificates.Add(cert2);
_clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
//Pretend this is our long-living HttpClient
var client = new HttpClient(_clientHandler);
//Now if we make a post request, will both certs be used?
using (HttpResponseMessage response = _client.PostAsync("https://one.somedomain.com", content).Result)
{
//...elided...
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 .NET Core 3.1 开发 ASP.NET Web 应用程序。该应用程序从具有错误的外部网络服务器下载 mp3 文件:响应标头中的 Content-Length 报告的字节数高于 mp3 的实际字节数。
这是使用 curl 从该服务器下载文件的示例:
curl -sSL -D - "http://example.com/test.mp3" -o /dev/null
HTTP/1.1 200 OK
Cache-Control: private
Pragma: no-cache
Content-Length: 50561024
Content-Type: audio/mpeg
Content-Range: bytes 0-50561023/50561024
Expires: 0
Accept-Ranges: 0-50561023
Server: Microsoft-IIS/10.0
Content-Transfer-Encoding: binary
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 03 Jan 2020 23:43:54 GMT
curl: (18) transfer closed with 266240 bytes remaining to read
Run Code Online (Sandbox Code Playgroud)
因此,即使 curl 报告传输不完整,mp3 也完全下载了 50294784 字节,我可以在我尝试过的任何音频播放器中打开它。
我在我的 Web 应用程序中想要的是与 curl 相同的行为:忽略不正确的 Content-Length 并下载 …