我正在做一个我命名为“主项目”的项目。我在那里至少有 10 个不同的小项目,这个项目可能会增长。我对所有这些项目都大摇大摆,因为所有这些项目都只使用一个 dotnet 核心 Web 应用程序来实现泛化目的。
例如,假设我有名为
SchoolJob
的项目和名为HospitalJob
的项目。 SchoolJob
有三个不同的端点,名为 GetStudents
、TakeStudents
、GetPayment
和 HostpitalJob
有两个端点,分别名为 GetDoctors
和 GetNurses
。这两个不同的项目将在一个 swagger UI 中看到:
- ../schooljob/getstudents
- ../schooljob/takestudents
- ../schooljob/getpayment
- ../hospitaljob/getdoctors
- ../hospitaljob/getnurses
我想做的是在一个 dotnet 核心 web 项目中设置多个不同的 swagger 页面,或者将一个 swagger 分组,这样它们就会出现在不同的页面/或同一页面上,但不是在同一时间。
../mainproject/swagger1/index.html 或 mainproject/swagger/schooljob UI 应该是这样的:
- ../schooljob/getstudents
- ../schooljob/takestudents
- ../schooljob/getpayment
../mainproject/swagger2/index.html 或 mainproject/swagger/hospitaljob UI 应该是这样的
- ../hospitaljob/getdoctors
- ../hospitaljob/getnurses
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
c.SwaggerDoc("schooljob", new OpenApiInfo
{
Version = "schooljob",
Title = "School Job"
});
c.SwaggerDoc("hospitaljob", new OpenApiInfo
{
Version = "hospitaljob",
Title = "Hospital Job"
});
// c.AddSecurityDefinition... and other swagger configurations
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
app.UseSwagger(c =>
{
c.RouteTemplate = "mainproject/swagger/{documentname}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/mainproject/swagger/schooljob/swagger.json", "School Job");
c.SwaggerEndpoint("/mainproject/swagger/hospitaljob/swagger.json", "Hospital Job");
c.RoutePrefix = "mainproject/swagger";
/c second prefix how?
});
}
// SchoolController.cs
[HttpPost("schooljob/getstudents")]
[ApiExplorerSettings(GroupName = "schooljob")]
public JsonResult GetStudents([FromBody]OnaySayfasiId onaySayfasi)
{ ... }
// HospitalController.cs
[HttpPost("hospitaljob/getdoctors")]
[ApiExplorerSettings(GroupName = "hospitaljob")]
public JsonResult GetDoctors([FromBody]OnaySayfasiId onaySayfasi)
{ ... }
顺便说一句,我尝试使用 Api 版本分组,但我再次看到了所有这些端点。有什么方法可以做到这一点?
我明白你错过了什么,你使用了错误的控制器属性,在这里你可以做什么:
[ApiVersion]
而不是 [ApiExplorerSettings(GroupName = ...)]
属性。组是不同的,我猜他们是关于在 Swagger 页面的同一部分下对端点进行分组。OpenApiInfo
, SwaggerEndpoint
, ApiVersion
需要相同的字符串,例如 schooljob
而不是 School Job
.我想如果您按以下方式更新代码,它应该可以工作:
// Startup.cs
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/mainproject/swagger/schooljob/swagger.json", "schooljob");
c.SwaggerEndpoint("/mainproject/swagger/hospitaljob/swagger.json", "hospitaljob");
c.RoutePrefix = "mainproject/swagger";
// No need for 2nd route prefix as there is only one Swagger page,
// the content of the page gets updated when selecting a different version in the combobox.
});
/* This line may be required in ConfigureServices method, give it a try */
/* services.AddApiVersioning(); */
// SchoolController.cs
[HttpPost("schooljob/getstudents")]
[ApiVersion("schooljob")]
public JsonResult GetStudents([FromBody]OnaySayfasiId onaySayfasi)
{ ... }
希望它能解决您的问题!
在 program.cs (.net 6) 中使用以下代码,如果您使用的是 .net 5(或以下版本),请在 strartup.cs 中使用此代码
services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VV";
options.SubstituteApiVersionInUrl = true;
});
services.AddSwaggerGen(options =>
{
options.DocInclusionPredicate((documentName, apiDescription) =>
{
var actionApiVersionModel = apiDescription.ActionDescriptor.GetApiVersionModel();
var apiExplorerSettingsAttribute = (ApiExplorerSettingsAttribute)apiDescription.ActionDescriptor.EndpointMetadata.First(x => x.GetType().Equals(typeof(ApiExplorerSettingsAttribute)));
if (actionApiVersionModel == null)
{
return true;
}
if (actionApiVersionModel.DeclaredApiVersions.Any())
{
return actionApiVersionModel.DeclaredApiVersions.Any(v =>
$"{apiExplorerSettingsAttribute.GroupName}v{v}" == documentName);
}
return actionApiVersionModel.ImplementedApiVersions.Any(v =>
$"{apiExplorerSettingsAttribute.GroupName}v{v}" == documentName);
});
var apiVersionDescriptionProvider = services.BuildServiceProvider().GetService<IApiVersionDescriptionProvider>();
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
options.SwaggerDoc($"Orders{description.GroupName}", new OpenApiInfo
{
Title = "Example Service",
Description = "Example Service -- Backend Service Project",
Version = description.ApiVersion.ToString(),
});
options.SwaggerDoc($"Payments{description.GroupName}", new OpenApiInfo
{
Title = "Example Service",
Description = "Example Service -- Backend Service Project",
Version = description.ApiVersion.ToString(),
});
// Orders & Payments are the groupName above ex: out put will be : swagger/OrdersV1.0/swagger.json ( if you select Orders from the swagger definition dropdown)
// If you select Payments => output : swagger/PaymentsV1.0/swagger.json
}
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(
swaggerOptions =>
{
foreach (var description in provider.ApiVersionDescriptions)
{
swaggerOptions.SwaggerEndpoint($"{swagger/Orders{description.GroupName}/swagger.json",$"Orders {description.GroupName.ToUpperInvariant()}" );
swaggerOptions.SwaggerEndpoint($"{swagger/Payments{description.GroupName}/swagger.json", $"Payments {description.GroupName.ToUpperInvariant()}");
}
});
控制器 //V1 // 示例控制器 1:
[ApiVersion("1.0")]
[ApiController]
[ApiExplorerSettings(GroupName = "Orders")]
[Route("api/v{version:apiVersion}/[controller]")]
public class OrdersController : ControllerBase
// 示例控制器 2:
[ApiVersion("1.0")]
[ApiController]
[ApiExplorerSettings(GroupName = "Payments")]
[Route("api/v{version:apiVersion}/[controller]")]
public class PaymentsController : ControllerBase