我有一个具有以下 API 端点的 .NET API 项目,但 Swagger UI 和生成的 swagger.json 文件仅显示 PetJsonRequestInfo 模型类的选项,而不管内容类型如何。我需要配置 Swagger 以根据内容类型(multipart/form-data 和 application/json)正确显示不同的模型类。
这是我的 API 端点的相关代码:
public class PetRequestInfo
{
// File upload specific to multipart/form-data
public IFormFile PetImage { get; set; }
// Common properties
public string PetName { get; set; }
public int PetAge { get; set; }
}
public class PetJsonRequestInfo
{
// No file upload, JSON only
// Common properties
public string PetName { get; set; }
public int PetAge { get; set; }
}
// POST: api/pets/add
[HttpPost("add")]
[Consumes("multipart/form-data", "application/json")]
public async Task<ActionResult<PetAdded>> AddPet([FromForm] PetRequestInfo petRequestInfo, [FromBody] PetJsonRequestInfo petJsonRequestInfo)
{
// Validate inputs
if (petRequestInfo == null || petJsonRequestInfo == null)
{
return BadRequest("Invalid request data.");
}
// logic will be here...
}
Swagger 文件当前如下所示:
"/v1/Pet/add": {
"post": {
"summary": "Add a new pet.",
"requestBody": {
"description": "The pet request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PetJsonRequestInfo"
}
},
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/PetJsonRequestInfo"
}
},
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/PetJsonRequestInfo"
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PetAdded"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResult"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResult"
}
}
}
}
}
}
}
我希望 Swagger 文档能够根据内容类型反映正确的模型类,如下所示。我怎样才能实现这个目标?任何帮助将不胜感激!
"requestBody": {
"description": "The pet request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PetJsonRequestInfo"
}
},
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/PetRequestInfo"
}
},
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/PetRequestInfo"
}
}
}
}
您可以实施
CustomOperationFilter
来实现这一目标。比如下面这样:当relavatePath为“api/pets/add”时更改操作
public class CustomOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.ApiDescription.RelativePath.Equals("api/pets/add", StringComparison.OrdinalIgnoreCase))
{
operation.RequestBody.Content.Clear();
operation.RequestBody.Content.Add("application/json", new OpenApiMediaType
{
Schema = context.SchemaGenerator.GenerateSchema(typeof(PetJsonRequestInfo), context.SchemaRepository)
});
operation.RequestBody.Content.Add("multipart/form-data", new OpenApiMediaType
{
Schema = context.SchemaGenerator.GenerateSchema(typeof(PetRequestInfo), context.SchemaRepository)
});
}
}
}
在program.cs中添加过滤器
builder.Services.AddSwaggerGen(c =>
{
c.OperationFilter<CustomOperationFilter>();
});
使用动态类型创建动作。
[Route("api/[controller]")]
[ApiController]
public class petsController : ControllerBase
{
[HttpPost("add")]
public void AddPet(dynamic requestBody)
{
}
}