ASP.NET Core Web API中如何校验POST请求体JSON必填字段?
解决ASP.NET Core JSON请求体必填字段验证问题
问题根源在于:Guid、int这类值类型本身自带默认值(Guid.Empty、0),模型绑定器会自动填充这些默认值,导致[Required]属性无法触发验证——ModelState会认为字段已被“赋值”(哪怕是默认值)。
以下是三种适配不同场景的解决方案:
1. 全局配置强制所有字段必填(最适合大量模型的场景)
通过配置System.Text.Json序列化规则,要求所有模型属性必须出现在JSON请求体中,缺失则直接触发反序列化异常,ASP.NET Core会自动返回400错误。
在Program.cs中添加配置:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddJsonOptions(options => { // 强制所有属性必须出现在JSON请求中 options.JsonSerializerOptions.Required = JsonRequired.Always; // 禁用默认值自动忽略(可选,确保默认值不会被序列化框架跳过) options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never; }); var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
若个别属性需设为可选,可在该属性上添加[JsonRequired(Required.Default)]覆盖全局规则。
2. 可空值类型+[Required]属性(灵活配置特定字段)
将需要验证的值类型改为可空类型,配合[Required]属性使用。当JSON中缺失字段时,属性值会为null,触发ModelState验证失败。
修改Person模型:
namespace JsonTest.Models; public class Person { [Required] public Guid? Id { get; set; } public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; [Required] public int? Age { get; set; } }
在Controller中检查ModelState:
[HttpPost] public IActionResult SavePerson([FromBody] Person person) { if (!ModelState.IsValid) { return BadRequest(ModelState); } return new JsonResult(new { person.Id, person.FirstName, person.LastName, person.Age }); }
3. 自定义验证属性检查默认值(不修改模型类型结构)
如果不想改变模型的类型定义,可以自定义验证属性,通过检查值类型是否为默认值来判断字段是否缺失。
自定义验证属性:
using System.ComponentModel.DataAnnotations; public class NotDefaultAttribute : ValidationAttribute { public override bool IsValid(object? value) { if (value == null) return false; var valueType = value.GetType(); // 引用类型直接通过(如需检查null可额外处理) if (!valueType.IsValueType) return true; // 获取值类型的默认值并对比 var defaultValue = Activator.CreateInstance(valueType); return !value.Equals(defaultValue); } }
在模型属性上应用该属性:
namespace JsonTest.Models; public class Person { [NotDefault(ErrorMessage = "Id不能为空")] public Guid Id { get; set; } public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; [NotDefault(ErrorMessage = "Age不能为空")] public int Age { get; set; } }
同样在Controller中检查ModelState.IsValid,返回BadRequest即可。
内容的提问来源于stack exchange,提问作者prbrq
相关产品推荐
相关产品推荐

