我试图在 for 循环内调用 HttpClient 请求,如下所示。它需要对第三方rest api进行多次连续调用。但它只在循环退出时给我第一个服务调用结果,然后再从其余的服务调用中获取结果。
private void Search()
{
try
{
var i = 1;
using (var httpClient = new HttpClient())
{
while (i < 5)
{
string url = "https://jsonplaceholder.typicode.com/posts/" + i;
var response = httpClient.GetAsync(url).Result;
string jsonResult = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(jsonResult.ToString());
i++;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用调试点运行时,程序会给出所有结果。但是当我在没有调试点的情况下运行它时,它只给出第一个结果。
我也尝试使用 async、await 方法。它也给了我同样的结果。
我觉得程序需要等待异步调用返回数据。
请帮我解决这个问题。
编辑-异步方式
private async Task<string> SearchNew()
{
try
{
var i = 1;
var res = string.Empty;
using (var httpClient = …Run Code Online (Sandbox Code Playgroud) 微软的HttpClient官方文档指出,如果我们想使用HttpClient下载大文件,我们应该
流式传输这些下载而不使用默认缓冲。如果使用默认缓冲,客户端内存使用量将变得非常大,可能导致性能大幅下降。
默认缓冲是什么?我们如何更改它,以便无论我们最终下载的文件大小如何,都不会遇到上述问题?
虚拟代码片段将不胜感激!
我想实现这个,有什么技巧吗
HttpClient c = new HttpClient();
c.DefaultRequestHeaders.Add("Content-type", "application/octet-stream"));
Run Code Online (Sandbox Code Playgroud) 使用 C#、.NET Core 3.1
我httpclient通过 in添加一个单例startup.cs:
services.AddHttpClient<IClientLogic, ClientLogicA>().ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
var cert= GetCertFromX();
handler.ClientCertificates.Add(cert);
return handler;
});
Run Code Online (Sandbox Code Playgroud)
但是,假设稍后在ClientLogicA课堂上,我想更改证书,我该如何执行此操作,并且更改是否会持续存在以供将来使用 httpclient 单例?
c# dependency-injection dotnet-httpclient asp.net-core httpclientfactory
我有一个自定义HttpMessageHandler实现:
public class MyHandler : DelegatingHandler
{
private readonly HttpClient _httpClient;
private readonly MyHandlerOptions _config;
public MyHandler(
HttpClient httpClient,
IOptions<MyHandlerOptions> options)
{
_httpClient = httpClient;
_config = options.Value;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = await GetAccessToken()
return await base.SendAsync(request, cancellationToken);
}
private async Task<string> GetAccessToken()
{
//some logic to get access token using _httpClient and _config
}
}
Run Code Online (Sandbox Code Playgroud)
它需要配置对象MyHandlerOptions。它的形式在这里并不那么重要。它基本上包含处理程序需要的 clientId、clientSecret 等,以了解如何获取访问令牌。
我有一些需要使用的服务(类型化的http客户端)MyHandler:
//registration of MyHandler itself
builder.Services.AddHttpClient<MyHandler>();
//configuration …Run Code Online (Sandbox Code Playgroud) 在基本层面上,我应该能够设置绝对值BaseAddress,HttpClient然后使用相对值发送 Http 请求Uri。期望的是相对的Uri将附加到基地址以进行 Http 调用。大多数情况下它都会这样做。这个例子效果很好。
编辑:见底部。从 Uris 的构建方式来看,这似乎是一种奇怪的行为。
var httpClient = new HttpClient() { BaseAddress = new Uri("http://restcountries.eu/rest/", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("v2", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var json = await httpResponseMessage.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)
提琴手网址:
获取http://restcountries.eu/rest/v2 HTTP/1.1
我有一个本地 API。当我在本地 API 上运行等效项时,调用会截断部分基地址(“Api”)。
var httpClient = new HttpClient() { BaseAddress = new Uri($"http://localhost/JsonPerson/Api", UriKind.Absolute) };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri("GetApiPerson", UriKind.Relative));
var httpResponseMessage = await httpClient.SendAsync(requestMessage);
var …Run Code Online (Sandbox Code Playgroud) 考虑到使用 HttpClient 的众所周知的困境和问题 - 即套接字耗尽和不尊重 DNS 更新,最好的做法是使用 IHttpClientFactory 并让容器决定何时以及如何利用 http 池连接效率。这一切都很好,但现在我无法在每个请求上使用自定义数据实例化自定义 DelegatingHandler。
下面的示例说明了我在使用工厂方法之前是如何做到的:
public class HttpClientInterceptor : DelegatingHandler
{
private readonly int _id;
public HttpClientInterceptor(int id)
{
_id = id;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// associate the id with this request
Database.InsertEnquiry(_id, request);
return await base.SendAsync(request, cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
每次实例化 HttpClient 时,都可以传递一个 Id:
public void DoEnquiry()
{
// Insert a new enquiry hypothetically
int id = Database.InsertNewEnquiry();
using (var http = new HttpClient(new HttpClientInterceptor(id))) …Run Code Online (Sandbox Code Playgroud) 我只是想创建一个简单的测试,在其中实例DelegateHandlers化 aHttpClient而不带 Asp.net Core 包。我有 2 个删除处理程序
ThrottlingDelegatingHandlerPolicyHttpMessageHandler(来自波莉包)我怎样才能将两者结合起来并传递给HttpClient?
var policy = HttpPolicyExtensions.HandleTransientHttpError().CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
var pollyHandler = new PolicyHttpMessageHandler(policy);
var http = new HttpClient(new ThrottlingDelegatingHandler(MaxParallelism, pollyHandler));
Run Code Online (Sandbox Code Playgroud)
上面给了我一个错误:System.InvalidOperationException : The inner handler has not been assigned.
没有PolicyHttpMessageHandler可以传递 的构造函数innerHandler。
我怎样才能做到这一点?
我使用 Polly 来处理一些场景,例如请求限制和超时。这些策略直接添加到 Startup.cs 中,如下所示:
var retries = //applying the retries, let say I set to 25 times with 10s delay. Total 250s.
serviceCollection
.AddHttpClient<IApplicationApi, ApplicationApi>()
.AddPolicyHandler((services, request) => GetRetryPolicy<ApplicationApi>(retries, services));
Run Code Online (Sandbox Code Playgroud)
政策:
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy<T>(List<TimeSpan> retries, IServiceProvider services)
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
.WaitAndRetryAsync(retries,
onRetry: (outcome, timespan, retryAttempt, context) =>
{
//do some logging
}
}
Run Code Online (Sandbox Code Playgroud)
在 ApplicationApi.cs 中执行如下操作:
private readonly HttpClient _httpClient;
public ApplicationApi(HttpClient httpClient)
{
_httpClient = httpClient;
}
public void CallApi()
{
var …Run Code Online (Sandbox Code Playgroud) 我有一个 Blazor WASM 页面,需要进行调用以从 API 获取一些数据。Blazor 应用程序由 ASPNetCore 托管,并且托管应用程序包含 API。
我的一些端点可以工作,但一些调用会引发 Json 序列化异常。
渲染组件未处理的异常:“<”是值的无效开头。路径: $ | 行号: 0 | 内联字节位置:0。
如果我查看服务器的实际响应,它看起来像是从我的 WASM 应用程序返回 index.html 的内容。
控制器示例
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class CompanyController : ControllerBase
{
private readonly ApplicationDbContext _context;
public CompanyController(ApplicationDbContext context)
{
_context = context;
}
[HttpGet("{id}")]
public async Task<IActionResult> Get(long id)
{
Company? company = await _context.Companies.FindAsync(id);
if (company == null)
{
return NotFound();
}
return Ok(company);
}
}
Run Code Online (Sandbox Code Playgroud)
Blazor 页面示例
@page "/companies/{id:long}"
@attribute [Authorize]
@inject HttpClient Http …Run Code Online (Sandbox Code Playgroud)