首页 > 解决方案 > Swashbuckle 不更新 specification.json

问题描述

Swashbuckle 已停止更新我的 .NET Core 3.1 Web API 的 specification.json 文件。每当我在本地以调试模式运行站点时,它都会自动更新文件,现在它不会了。我没有更改我的 Startup.cs 文件中指定这一点的那部分,并且当我运行npm cinpm install在该站点的ClientApp文件夹中时,我没有收到任何相关的警告/警报。

Swagger UI 本身仍然根据我现有的 specification.json (作为 wwwroot 文件夹的直接子级存在)工作。当我更新 API 端点时,该文件不再更新。我怎样才能解决这个问题?

编辑:凭直觉,我在里面设置了断点services.AddSwaggerGen(我在其中指定包含 XML 注释,并发现断点永远不会命中。我怀疑这是问题的根源,但我不明白可能是什么干扰。我的应用程序没有抛出任何异常。

从 Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddApplication();
    services.AddInfrastructure(Configuration);

    services.AddSingleton<ICurrentUserService, CurrentUserService>();

    services.AddHttpContextAccessor();

    services.AddHealthChecks();

    services.AddControllersWithViews()
            .AddFluentValidation();

    services.AddRazorPages();

    // Customize default API behaviour
    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    });

    // In production, the Angular files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/dist";
    });

    services.AddOpenApiDocument(configure =>
    {
        configure.Title = "My API";
        configure.AddSecurity("JWT", Enumerable.Empty<string>(), new OpenApiSecurityScheme
        {
            Type = OpenApiSecuritySchemeType.ApiKey,
            Name = "Authorization",
            In = OpenApiSecurityApiKeyLocation.Header,
            Description = "Type into the textbox: Bearer {your JWT token}."
        });

        configure.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT"));
    });
    services.AddSwaggerGen(c =>
    {
        // Configure Swagger to use the xml documentation file
        var xmlFile = System.IO.Path.ChangeExtension(typeof(Startup).Assembly.Location, ".xml");
        c.IncludeXmlComments(xmlFile);
    });

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["JWT:Issuer"],
                ValidAudience = Configuration["JWT:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Key"])) // todo : move to environment variable
            };

            options.Events = new JwtBearerEvents
            {
                OnChallenge = context =>
                {
                    return Task.CompletedTask;
                },
                OnAuthenticationFailed = context =>
                {
                    if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                    {
                        context.Response.Headers.Add("Token-Expired", "true");
                    }
                    return Task.CompletedTask;
                }
            };
        });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    loggerFactory.AddLog4Net();

    app.UseHealthChecks("/health");
    //app.UseHttpsRedirection(); // HttpsRedirection here breaks the Azure AppService.
    app.UseStaticFiles();
    if (!env.IsDevelopment())
    {
        app.UseSpaStaticFiles();
    }

    app.UseSwaggerUi3(settings =>
    {
        settings.Path = "";
        settings.DocumentPath = "/specification.json";
    });

    app.UseCors(u => u.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

    app.UseRouting();

    app.UseAuthentication();
    //app.UseIdentityServer();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller}/{action=Index}/{id?}");
        endpoints.MapRazorPages();
        //endpoints.MapControllers()
        //    .RequireAuthorization("ApiScope");
    });
}

标签: swaggerswashbuckle.aspnetcore

解决方案


推荐阅读