如何在ASP.NET Core WebApi中支持OpenApi的OneOf及多请求体Schema
ASP.NET Core WebApi 实现oneOf多Schema请求体方案
ASP.NET Core WebApi完全支持OpenApi规范的oneOf特性,可实现同一个接口接收两种不同结构的请求体,具体可通过以下两种主流方案实现:
方案1:基于Swashbuckle.AspNetCore自定义过滤器(原生实现)
无需引入额外第三方专用包,适配灵活度高:
- 第一步:安装基础NuGet依赖,版本要求6.0及以上
Install-Package Swashbuckle.AspNetCore - 第二步:定义你需要支持的多种请求结构,示例如下:
// 文本消息请求结构 public class TextMessage { public string Content { get; set; } public int TextLength { get; set; } } // 图片消息请求结构 public class ImageMessage { public string ImageUrl { get; set; } public int Width { get; set; } public int Height { get; set; } } - 第三步:自定义Schema过滤器实现oneOf规范适配
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; public class OneOfSchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { // 此处可根据自己的业务需求替换为要适配的请求类型判断 if (context.Type == typeof(object)) { schema.OneOf = new List<OpenApiSchema> { context.SchemaGenerator.GenerateSchema(typeof(TextMessage), context.SchemaRepository), context.SchemaGenerator.GenerateSchema(typeof(ImageMessage), context.SchemaRepository) }; // 清空默认生成的冗余属性 schema.Properties.Clear(); schema.Type = null; } } } - 第四步:在Program.cs中注册过滤器
var builder = WebApplication.CreateBuilder(args); // 其他服务注册逻辑... builder.Services.AddSwaggerGen(opt => { opt.SchemaFilter<OneOfSchemaFilter>(); }); - 第五步:接口适配,可通过JsonElement接收请求后手动反序列化匹配对应结构
[HttpPost("send-message")] public IActionResult SendMessage([FromBody] JsonElement requestBody) { var rawJson = requestBody.GetRawText(); // 判断请求结构匹配对应类型 if (requestBody.TryGetProperty("content", out _)) { var textMsg = System.Text.Json.JsonSerializer.Deserialize<TextMessage>(rawJson); // 处理文本消息逻辑 return Ok($"处理文本消息成功,内容长度:{textMsg.TextLength}"); } else if (requestBody.TryGetProperty("imageUrl", out _)) { var imageMsg = System.Text.Json.JsonSerializer.Deserialize<ImageMessage>(rawJson); // 处理图片消息逻辑 return Ok($"处理图片成功,尺寸:{imageMsg.Width}*{imageMsg.Height}"); } return BadRequest("不支持的请求结构"); }
方案2:使用OneOf专用包简化实现
开发效率更高,自动适配oneOf规范生成Swagger文档:
- 第一步:安装所需NuGet包
Install-Package OneOf Install-Package Swashbuckle.AspNetCore.OneOf - 第二步:在Program.cs中启用oneOf支持
builder.Services.AddSwaggerGen(opt => { opt.UseOneOfForPolymorphism(); }); - 第三步:直接在接口定义时指定多种请求类型即可
[HttpPost("send-message")] public IActionResult SendMessage([FromBody] OneOf<TextMessage, ImageMessage> request) { // 自动匹配对应类型执行逻辑 return request.Match( textMsg => Ok($"处理文本消息成功,内容长度:{textMsg.TextLength}"), imageMsg => Ok($"处理图片成功,尺寸:{imageMsg.Width}*{imageMsg.Height}") ); }
内容的提问来源于stack exchange,提问作者Dinesh
相关产品推荐
相关产品推荐

