我有配置 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.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";
}
});
}