如何在.NET API中配置Swagger根据内容类型显示不同的模型类

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

我有一个具有以下 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"
            }
        }
    }
}
asp.net-core sdk swagger openapi swashbuckle.aspnetcore
1个回答
0
投票

您可以实施

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)
        {
        }
    }

测试结果
enter image description here enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.