[英]HttpClient - Request was canceled - Timeout of 100 seconds elapsing
I am using a blazor web assembly project followed by a asp.net core web api and a shared project.我正在使用一个 blazor web 装配项目,然后是一个 asp.net 核心 web api 和一个共享项目。 When running my two projects and pulling up post man to perform a GET request
https://localhost:5011/api/WebReport/GatherAllReports
it hits the ReporterRepository
from the blazor web assembly and when it hits the very first line var response
it stays on that line then eventually after a really long time it says on postman...当运行我的两个项目并拉起邮递员执行 GET 请求
https://localhost:5011/api/WebReport/GatherAllReports
它从 blazor web 程序集命中ReporterRepository
并且当它命中第一行var response
时它保持打开那条线在很长一段时间后最终在 postman 上说...
System.Threading.Tasks.TaskCanceledException: The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing. System.Threading.Tasks.TaskCanceledException:由于配置的 HttpClient.Timeout 已过 100 秒,请求被取消。
---> System.TimeoutException: The operation was canceled.
---> System.TimeoutException: 操作被取消。
---> System.Threading.Tasks.TaskCanceledException: The operation was canceled.
---> System.Threading.Tasks.TaskCanceledException: 操作被取消。
---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
---> System.IO.IOException:无法从传输连接中读取数据:由于线程退出或应用程序请求,I/O 操作已中止。
---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
---> System.Net.Sockets.SocketException (995): 由于线程退出或应用程序请求,I/O 操作已中止。
--- End of inner exception stack trace ------ 内部异常堆栈跟踪结束 ---
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
在 System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError 错误,CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
在 System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 令牌)
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
在 System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter 适配器,内存`1 缓冲区)
at System.Net.Http.HttpConnection.FillAsync(Boolean async)
在 System.Net.Http.HttpConnection.FillAsync(布尔异步)
at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean async, Boolean foldedHeadersAllowed)
在 System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(布尔异步,Boolean foldedHeadersAllowed)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
在 System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage 请求,Boolean 异步,CancellationToken cancellationToken)
--- End of inner exception stack trace ---
--- 内部异常堆栈跟踪结束 ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
在 System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage 请求,Boolean 异步,CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage 请求,Boolean 异步,Boolean doRequestAuth,CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,Boolean 异步,CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
在 System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage 请求,Boolean 异步,CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
在 Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
在 Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
在 System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage 请求,HttpCompletionOption completionOption,Boolean 异步,Boolean emitTelemetryStartStop,CancellationToken cancellationToken)
--- End of inner exception stack trace ---
--- 内部异常堆栈跟踪结束 ---
and much more other messages returned in postman.以及 postman 中返回的更多其他消息。
Is there a reason why this is occurring whenever I call the route endpoint for my web api controller?每当我为我的 web api controller 调用路由端点时,是否会发生这种情况?
Web API Controller: Web API Controller:
using BlazorReports.Services; // this contains the `ReporterRepository.cs` file
[Route("api/[controller]")]
[ApiController]
public class WebReportController : ControllerBase
{
private readonly ReporterRepository_repo;
public WebReportController (ReporterRepository repo)
{
_repo = repo;
}
[HttpGet]
[Route("GatherAllReports")]
public async Task<IActionResult> Get()
{
var reportValues = await _repo.GetAll();
return Ok(reportValues);
}
}
startup.cs
for web api: web api 的
startup.cs
:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration;公共 class 启动 { 公共启动(IConfiguration 配置){ 配置 = 配置; }
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebAPI", Version = "v1" });
});
services.AddDbContext<ReportContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Default")));
services.AddScoped<IReporterRepository, ReporterRepository>();
services.AddHttpClient<IReporterRepository, ReporterRepository>(client =>
{
client.BaseAddress = new Uri("https://localhost:5011/");
});
services.AddHttpContextAccessor();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebAPI v1"));
}
app.UseHttpsRedirection();
app.UseCors(opt => opt
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true)
.AllowCredentials());
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
} }
In my blazor web assembly project:在我的 blazor web 组装项目中:
IReporterRepository.cs:
public interface IReporterRepository
{
Task<List<Reports>> GetAll();
}
ReporterRepository.cs:
public class ReporterRepository: IReporterRepository
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options;
public ReporterRepository(HttpClient httpClient)
{
_httpClient = httpClient;
_options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
}
public async Task<List<Reports>> GetAll()
{
var response = await _httpClient.GetAsync("/ReportsPage/GatherAllReports");
var content = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
throw new ApplicationException(content);
}
var results = JsonSerializer.Deserialize<List<Reports>>(content, _options);
return results;
}
}
You are going in infinite loop because your GetAll() method is calling itself.您将进入无限循环,因为您的 GetAll() 方法正在调用自身。 Your code should look like this:
您的代码应如下所示:
public class ReporterAccessLayer
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options;
public ReporterAccessLayer(HttpClient httpClient)
{
_httpClient = httpClient;
_options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
_repository = repository;
}
public async Task<List<Reports>> GetAll()
{
try
{
return await httpClient.GetAsync<List<Reports>>("/ReportsPage/GatherAllReports");
}
catch
{
// do exception handling
}
}
}
Your request is timing out because you have created an infinite loop.您的请求超时,因为您创建了一个无限循环。
WebReportController.Get()
invokes ReporterRepository.GetAll()
which in turn makes an HTTP request back to WebReportController.Get()
and you're back where you started. WebReportController.Get()
调用ReporterRepository.GetAll()
,后者又向WebReportController.Get()
发出 HTTP 请求,您就回到了起点。 For the pattern you appear to be using, where your controller actions call into a service class to perform business logic (which is a good pattern), you would call into your Data Access Layer where your report data is held.对于您似乎正在使用的模式,您的 controller 操作调用服务 class 来执行业务逻辑(这是一个很好的模式),您将调用保存报告数据的数据访问层。 You are not actually retrieving any report data in the code you have provided.
您实际上并没有在您提供的代码中检索任何报告数据。
For example:例如:
public async Task<List<Reports>> GetAll()
{
var reportA = await _reports.GetReportA();
var reportB = await _reports.GetReportA();
// do any further business logic or error handling here
return new List<Reports> { reportA, reportB };
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.