如何在API请求体中兼容0/1与false/true两种布尔值格式
兼容可空布尔值的0/1与true/false格式并保持Swagger文档正确的解决方案
核心思路
由于[FromBody]依赖JSON序列化框架(默认System.Text.Json),无需使用IModelBinder,通过自定义JSON转换器处理整数与布尔值的映射即可,既不破坏请求体绑定逻辑,也能让Swagger正常识别模型结构。
步骤1:实现自定义可空布尔值JSON转换器
创建继承自JsonConverter<bool?>的转换器,处理输入的整数、布尔字符串及空值:
using System.Text.Json; using System.Text.Json.Serialization; public class NullableBooleanJsonConverter : JsonConverter<bool?> { public override bool? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) { case JsonTokenType.Number: var intValue = reader.GetInt32(); return intValue switch { 0 => false, 1 => true, _ => null // 非0/1整数返回null,可按需改为抛出异常 }; case JsonTokenType.True: return true; case JsonTokenType.False: return false; case JsonTokenType.Null: return null; default: throw new JsonException($"无法将{reader.TokenType}类型转换为可空布尔值"); } } public override void Write(Utf8JsonWriter writer, bool? value, JsonSerializerOptions options) { // 序列化时默认输出布尔值,也可改为输出0/1 if (value.HasValue) writer.WriteBooleanValue(value.Value); else writer.WriteNullValue(); } }
步骤2:注册转换器到全局JSON配置
在Program.cs(或Startup.cs)中配置控制器的JSON序列化选项,添加自定义转换器:
var builder = WebApplication.CreateBuilder(args); // 添加控制器并配置JSON转换器 builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new NullableBooleanJsonConverter()); }); // 保留原有Swagger配置 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 中间件配置 app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
步骤3:修复控制器的空引用问题
原控制器代码直接判断if(requestData.Status)会触发空引用异常(当Status为null时),修改为:
[HttpPost, Route("")] public async Task<IActionResult> RequestStatus([FromBody] StatusRequest requestData ) { if (requestData.Status.HasValue && requestData.Status.Value) { return Ok(); } else { return BadRequest(); } }
步骤4:保证Swagger文档正确显示
基础文档支持
保留[FromBody]属性后,Swagger会自动将StatusRequest识别为请求体模型,无需额外调整。
添加多格式示例(可选)
若需在文档中展示0/1和true/false两种请求格式,可通过自定义操作过滤器实现:
public class StatusRequestExampleFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.RequestBody == null) return; // 布尔值格式示例 var booleanExample = new OpenApiObject { ["Status"] = new OpenApiBoolean(true) }; // 整数格式示例 var intExample = new OpenApiObject { ["Status"] = new OpenApiInteger(1) }; operation.RequestBody.Content["application/json"].Examples.Add("布尔值格式", new OpenApiExample { Summary = "布尔值格式", Value = booleanExample }); operation.RequestBody.Content["application/json"].Examples.Add("整数格式", new OpenApiExample { Summary = "整数格式(0=false,1=true)", Value = intExample }); } }
注册过滤器到Swagger配置:
builder.Services.AddSwaggerGen(options => { options.OperationFilter<StatusRequestExampleFilter>(); });
验证效果
- 请求体
{"Status": 1}会被转换为true,返回Ok - 请求体
{"Status": 0}会被转换为false,返回BadRequest - 请求体
{"Status": true}/{"Status": false}正常处理 - 请求体
{"Status": null}或不传递Status字段时,requestData.Status为null,返回BadRequest - Swagger文档中请求体模型正常显示,且能看到两种格式的示例
内容的提问来源于stack exchange,提问作者Sigmarod
相关产品推荐
相关产品推荐

