【问题标题】:Timeout error in trying to access swagger.json in IHostedService through a httpclient call尝试通过 httpclient 调用访问 IHostedService 中的 swagger.json 时出现超时错误
【发布时间】:2021-09-30 13:57:47
【问题描述】:

我想访问 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: I/O 操作由于线程退出或应用程序请求而中止。

我在这里缺少什么?访问swagger.json 以构建自定义 API 游乐场应用程序的正确方法是什么?

【问题讨论】:

  • 写一个api来读取swagger.json的内容,然后向这个api发送请求获取数据?
  • 我被困在以编程方式阅读 swagger.json 的内容
  • 感谢您的回复,根据您的 sn-p,您似乎正在发送一个 http 请求以从另一台服务器获取 json 文件内容。我的意思是你可以在那个服务器程序中写reading content code
  • 我尝试了您提供的方式,但这也不起作用。它仍然让我遇到超时错误。因为 swagger.json 在任何文件夹中实际上都不可用。
  • 我在下面展示了我的想法,这里你说is not physically available in any folder,那么为什么你尝试通过https://localhost:44397/swagger/v1/swagger.json 访问文件呢?先生,我很困惑。

标签: c# asp.net-core swagger asp.net-core-5.0 swashbuckle.aspnetcore


【解决方案1】:

SwaggerMiddleware 处理服务 OpenAPI 文档。我们可以将其用作自己构建文档的参考。

首先向 DI 注册 SwaggerGenerator

// Startup.Configure
services.AddTransient<SwaggerGenerator>();

然后将其注入到一个类中,这里我使用一个端点直接为它提供服务:

// 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));
    });
});

【讨论】:

    【解决方案2】:

    我相信实际的 JSON 不一定是一个有效的端点,这本身可能就是一个问题。您是否尝试过在端点路由上没有显式文件名的调用?

    【讨论】:

    • 你的意思是这样的_httpClient.GetAsync("swagger/v1/swagger");?
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2021-05-29
    相关资源
    最近更新 更多