尝试通过 httpclient 调用访问 IHostedService 中的 swagger.json 时出现超时错误
Timeout error in trying to access swagger.json in IHostedService through a httpclient call
我想访问 swagger.json 文件并将其反序列化并存储到缓存中。
我正在 IHostedService
中进行异步调用。
public class InitializeCacheService : IHostedService
{
private IMemoryCache _cache;
public static readonly string swaggerJson = "swagger.json";
private readonly HttpClient _httpClient;
private readonly IServiceProvider _serviceProvider;
public InitializeCacheService(IMemoryCache cache, HttpClient client, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_httpClient = client;
_cache = cache;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
if (!_cache.TryGetValue(swaggerJson, out SwaggerDocumentCache cacheEntry))
{
_httpClient.BaseAddress = new Uri("https://localhost:44397");
var response = await _httpClient.GetAsync("swagger/v1/swagger.json");
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync();
cacheEntry = await JsonSerializer.DeserializeAsync
<SwaggerDocumentCache>(responseStream);
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
_cache.Set(swaggerJson, cacheEntry, cacheEntryOptions);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
但是应用程序一直在旋转,并且正在超时
var response = await _httpClient.GetAsync("swagger/v1/swagger.json");
它给出的错误是:
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.
我在这里缺少什么?访问 swagger.json
以构建自定义 API 游乐场应用程序的正确方法是什么?
我认为实际的 JSON 不一定是有效的端点,这本身可能就是一个问题。您是否尝试过在端点路由上没有显式文件名的情况下进行调用?
SwaggerMiddleware 处理服务 OpenAPI 文档。我们可以以此为参考来自己构建文档。
首先使用 DI 注册 SwaggerGenerator
:
// Startup.Configure
services.AddTransient<SwaggerGenerator>();
然后将其注入到 class 中,这里我使用端点直接为其提供服务:
// Startup.Configure
app.UseEndpoints(e =>
{
// ...
e.MapGet("/openapi.json", context =>
{
// inject SwaggerGenerator
var swaggerGenerator = context.RequestServices.GetRequiredService<SwaggerGenerator>();
// document name is defined in Startup.ConfigureServices method inside the AddSwaggerGen call
var doc = swaggerGenerator.GetSwagger("v1");
// serialize the document as json
using var writer = new StringWriter(CultureInfo.InvariantCulture);
var serializer = new OpenApiJsonWriter(writer);
doc.SerializeAsV3(serializer);
var json = writer.ToString(); // this is the openapi document
// serve it as json
context.Response.ContentType = MediaTypeNames.Application.Json;
return context.Response.WriteAsync(json, new UTF8Encoding(false));
});
});
我想访问 swagger.json 文件并将其反序列化并存储到缓存中。
我正在 IHostedService
中进行异步调用。
public class InitializeCacheService : IHostedService
{
private IMemoryCache _cache;
public static readonly string swaggerJson = "swagger.json";
private readonly HttpClient _httpClient;
private readonly IServiceProvider _serviceProvider;
public InitializeCacheService(IMemoryCache cache, HttpClient client, IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_httpClient = client;
_cache = cache;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
if (!_cache.TryGetValue(swaggerJson, out SwaggerDocumentCache cacheEntry))
{
_httpClient.BaseAddress = new Uri("https://localhost:44397");
var response = await _httpClient.GetAsync("swagger/v1/swagger.json");
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync();
cacheEntry = await JsonSerializer.DeserializeAsync
<SwaggerDocumentCache>(responseStream);
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
_cache.Set(swaggerJson, cacheEntry, cacheEntryOptions);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
但是应用程序一直在旋转,并且正在超时
var response = await _httpClient.GetAsync("swagger/v1/swagger.json");
它给出的错误是:
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.
我在这里缺少什么?访问 swagger.json
以构建自定义 API 游乐场应用程序的正确方法是什么?
我认为实际的 JSON 不一定是有效的端点,这本身可能就是一个问题。您是否尝试过在端点路由上没有显式文件名的情况下进行调用?
SwaggerMiddleware 处理服务 OpenAPI 文档。我们可以以此为参考来自己构建文档。
首先使用 DI 注册 SwaggerGenerator
:
// Startup.Configure
services.AddTransient<SwaggerGenerator>();
然后将其注入到 class 中,这里我使用端点直接为其提供服务:
// Startup.Configure
app.UseEndpoints(e =>
{
// ...
e.MapGet("/openapi.json", context =>
{
// inject SwaggerGenerator
var swaggerGenerator = context.RequestServices.GetRequiredService<SwaggerGenerator>();
// document name is defined in Startup.ConfigureServices method inside the AddSwaggerGen call
var doc = swaggerGenerator.GetSwagger("v1");
// serialize the document as json
using var writer = new StringWriter(CultureInfo.InvariantCulture);
var serializer = new OpenApiJsonWriter(writer);
doc.SerializeAsV3(serializer);
var json = writer.ToString(); // this is the openapi document
// serve it as json
context.Response.ContentType = MediaTypeNames.Application.Json;
return context.Response.WriteAsync(json, new UTF8Encoding(false));
});
});