如何更改 swagger Route 端点 url 并保存 api 版本控制

问题描述 投票:0回答:1

我有配置 SwaggerUI 和 Enpoints Url 的启动文件

namespace AccountingService
{
    public class Startup
    {
        //public Startup(IConfiguration configuration, IHostEnvironment env, ILogger<Startup> logger) { }
 
       //public void ConfigureServices(IServiceCollection services){ }
 
        public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider, IApiVersionDescriptionProvider provider)
        {
            if (HostEnvironment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseIpRateLimiting();
            app.ConfigureCustomMiddleware(_appSettings);
            UserHelper.InitDependencies(serviceProvider.GetRequiredService<IUserDataService>());
            
            app.UseRouting();
            app.UseCors("MyPolicy");

            app.UseHttpsRedirection();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseTimezone();
            app.UseErrorService(serviceProvider);
            app.UseSession();

            app.UseUserService();
 
            if (_appSettings.Swagger.Enabled)
            {
                app.UseSwagger();
                app.UseSwaggerUI(options =>
                {
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        options.SwaggerEndpoint($"swagger/{description.GroupName}/swagger.json", description.GroupName.ToLowerInvariant());
                        options.RoutePrefix = string.Empty;
                    }
                });
            }
            
            //app.UseNamedSwagger(_appSettings.ServiceName, _appSettings.ServiceTitle, _appSettings.Version);

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

在这种情况下它是如何在 swagger url generic 中工作的 localhost:[端口]/swagger/{groupname}/swagger.json

我需要在这里将 swagger url 更改为例如 [name-service]/swagger/v1/swagger.json 它需要在 docker compose 上的 nginx 服务器上更正路由

当我尝试更改 SwaggerEndpoint 任何其他 url 值时,例如

_appSettings.ServiceName
if (_appSettings.Swagger.Enabled)
            {
                app.UseSwagger();
                app.UseSwaggerUI(options =>
                {
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        options.SwaggerEndpoint($"{_appSettings.ServiceName}/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                        options.RoutePrefix = string.Empty;
                    }
                });
            }

它完全坏了,与此无关。

当我尝试更改 only 路由前缀时出现同样的问题 结果

app.RoutePrefix = $"{_appSettings.ServiceName}/swagger";

我不知道如何正确地形成问题和问题案例。

但是当我使用其他方法UseNamedSwagger来生成swagger UI

app.UseNamedSwagger(_appSettings.ServiceName, _appSettings.ServiceTitle, _appSettings.Version);

而不是

app.UseSwaggerUI(options =>
                {
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        options.SwaggerEndpoint($"{_appSettings.ServiceName}/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                        options.RoutePrefix = string.Empty;
                    }
                });

它工作正常,并且 swagger url 更改正确,但这里我的版本控制消失了 v1,v2 但是我的版本控制消失了 v1,v2

这里补充一下我如何构建API控制器

    [Authorize]
    [ApiController]
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    public class ActsController : ControllerBase

我需要更改或添加以正确显示 swagger url“edo-service/swagger/v1/swagger”并且不会丢失我的版本控制定义(v1,v2)

ConfigureServices 方法(如果需要)

 public void ConfigureServices(IServiceCollection services)
        {
            _logger.LogTrace("Startup::ConfigureServices");

            //Enable Cors
            services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
            {
                builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
            }));

            // configure strongly typed settings objects
            _appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
            services.Configure<AppSettings>(Configuration.GetSection(nameof(AppSettings)));
            // configure jwt authentication
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);

            // configure swagger settings
            var swaggerSettings = Configuration.GetSection("SwaggerAdminSettings").Get<SwaggerSettingsModel>();

            services.Configure<ErrorServiceApiConfiguration>(
                Configuration.GetSection(nameof(ErrorServiceApiConfiguration)));

            services.AddAuthentication(..);

            // requires using Microsoft.Extensions.Options
            services.Configure<FormOptions>(o =>
            {
                o.ValueLengthLimit = int.MaxValue;
                o.MultipartBodyLengthLimit = int.MaxValue;
                o.MemoryBufferThreshold = int.MaxValue;
            });

            //Add IMapper profile configuration to DI
            var mapperConfig = new MapperConfiguration(mc => mc.AddProfile(new AutoMapperProfile()));
            services.AddSingleton(mapperConfig.CreateMapper());

           // many other services....

            // -- API Rate Limit Configuration --
            services.AddMemoryCache();
            services.AddInMemoryRateLimiting();
            services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
            services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));

            //Add Services here
            //==== CommonServiceTools services ====
            services.AddLogger();
            services.ConfigureCrud();
            services.AddExternalApi();
            services.AddWarehouseApi();
            services.AddInvoiceManager();
            // many other services....

            services.AddDistributedMemoryCache();
            services.AddSession();

            services.Configure<MinioSettings>(Configuration.GetSection(nameof(MinioSettings)));
            services.Configure<WarehouseApiSettings>(Configuration.GetSection(nameof(WarehouseApiSettings)));

            services.AddControllers(opt =>
            { opt.UseCentralRoutePrefix(new RouteAttribute(_appSettings.ServiceName)); })
                .AddNewtonsoftJson(options => options.UseMemberCasing())
                .AddJsonOptions(options =>
                    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())).SetCompatibilityVersion(CompatibilityVersion.Latest);

            //API versioning
            services.AddApiVersioning(
                o =>
                {
                    //o.Conventions.Controller<UserController>().HasApiVersion(1, 0);
                    o.ReportApiVersions = true;
                    o.AssumeDefaultVersionWhenUnspecified = true;
                    o.DefaultApiVersion = new ApiVersion(1, 0);
                    o.ApiVersionReader = new UrlSegmentApiVersionReader();
                }
            );

            // note: the specified format code will format the version as "'v'major[.minor][-status]"
            services.AddVersionedApiExplorer(
                options =>
                {
                    options.GroupNameFormat = "'v'VVV";

                    // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
                    // can also be used to control the format of the API version in route accounting-service
                    options.SubstituteApiVersionInUrl = true;
                });

            services.AddWkhtmltopdf();


            if (_appSettings.Swagger.Enabled)
            {
                // -- Swagger configuration -- 
                services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigurationSwaggerOptions>();
                // Register the Swagger generator, defining 1 or more Swagger documents
                services.AddSwaggerGen(c =>
                {
                    c.OperationFilter<SwaggerDefaultValues>();
                    c.UseAllOfToExtendReferenceSchemas();

                    //c.SwaggerDoc(_appSettings.Version, 
                    //    new OpenApiInfo { Title = _appSettings.ServiceTitle, Version = _appSettings.Version });
                    /*Authorization*/
                    var jwtSecurityScheme = new OpenApiSecurityScheme
                    {
                        Scheme = "bearer",
                        BearerFormat = "JWT",
                        Name = "JWT Authentication",
                        In = ParameterLocation.Header,
                        Type = SecuritySchemeType.Http,
                        Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",

                        Reference = new OpenApiReference
                        {
                            Id = JwtBearerDefaults.AuthenticationScheme,
                            Type = ReferenceType.SecurityScheme
                        }
                    };

                    c.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);

                    c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        { jwtSecurityScheme, Array.Empty<string>() }
                    });

                    //1-Get all the assemblies of the project to add the related XML Comments
                    Assembly currentAssembly = Assembly.GetExecutingAssembly();
                    AssemblyName[] referencedAssemblies = currentAssembly.GetReferencedAssemblies();
                    IEnumerable<AssemblyName> allAssemblies = null;

                    if (referencedAssemblies != null && referencedAssemblies.Any())
                        allAssemblies = referencedAssemblies.Union(new AssemblyName[] { currentAssembly.GetName() });
                    else
                        allAssemblies = new AssemblyName[] { currentAssembly.GetName() };

                    IEnumerable<string> xmlDocs = allAssemblies
                        .Select(a => Path.Combine(Path.GetDirectoryName(currentAssembly.Location), $"{a.Name}.xml"))
                        .Where(f => File.Exists(f));

                    //2-Add the path to the XML comments for the assemblies having enabled the doc generation
                    if (xmlDocs != null && xmlDocs.Any())
                    {
                        foreach (var item in xmlDocs)
                        {
                            c.IncludeXmlComments(item, includeControllerXmlComments: true);
                        }
                    }
                });
            }

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            _logger.LogDebug("Startup::Constructor::Settings loaded");
        }
c# swagger-ui swashbuckle
1个回答
0
投票

已解决,只需在上面评论即可

//c.SwaggerDoc(_appSettings.Version,
//    new OpenApiInfo { Title = _appSettings.ServiceTitle, Version = _appSettings.Version });

做这件事

 if (_appSettings.Swagger.Enabled)
            {
                app.UseSwagger(delegate (SwaggerOptions c)
                {
                    c.RouteTemplate = $"/{_appSettings.ServiceName}/swagger/{{documentName}}/swagger.json";
                }).UseSwaggerUI(options =>
                {
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        options.SwaggerEndpoint(
                            $"/{_appSettings.ServiceName}/swagger/{description.GroupName}/swagger.json",
                            $"{_appSettings.ServiceTitle} {description.GroupName}");
                        options.RoutePrefix = $"{_appSettings.ServiceName}/swagger";
                    }
                });
            }
© www.soinside.com 2019 - 2024. All rights reserved.