【问题标题】:.NET Core Web API model validation.NET Core Web API 模型验证
【发布时间】:2026-01-29 12:35:01
【问题描述】:

我有一个通常看起来像的方法

    public IActionResult SomeAction(Guid id, [FromBody] Request request)
    {
       //bunch of other stuff left out
       AnotherObject obj = Mapper.Map(request);
      if (ModelState.IsValid) {//only validation errors on the request object are found
//obj validation errors are ignored
}
    }

在 Request 类中,我使用 DataAnnotations 来测试模型状态,这些都可以正常工作。但是,在 AnotherObject 内部,我也在使用 DataAnnotations,当我在此函数中测试 ModelState 时,.NET 会从 Request 对象中看到验证错误,但在映射对象中却看不到。

此端点的调用者不知道 AnotherObject,也不需要。有没有办法让 .NET 尊重在控制器操作内部创建但未传入的对象的验证?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-webapi asp.net-core-2.1


    【解决方案1】:

    您可以使用Validator 对象手动测试对象:

    var obj = Mapper.Map(request);
    var context = new ValidationContext(obj, serviceProvider: null, items: null);
    var results = new List<ValidationResult>();
    
    var isValid = Validator.TryValidateObject(obj, context, results);
    

    更多信息请参见this short tutorial

    注意这不是递归的,根据AnotherObject的复杂程度,你可能需要自己使用Reflection来递归遍历对象。

    【讨论】:

    • 这确实按预期工作,遗憾的是你是正确的,我将不得不通过对象图递归。让 DataAnnotations 为我处理这件事会很好。
    【解决方案2】:

    ModelState 在将 JSON 转换为类型请求时验证模型。因此,ModelState 将针对空值和不匹配的类型进行验证。当您将 request 映射到 obj 时,不会发生对 ModelState 的调用。

    因此,使用:

    if (ModelState.IsValid) {
      AnotherObject obj = Mapper.Map(request);
    }
    

    在映射时验证模型...你真的不需要两个 ModelState 验证器

    【讨论】:

    • 假设他可以控制 Mapper.Map 输出的内容并且与 DataAnnotations 配合得很好。
    • 使用 Automapper 他只能在映射时验证类型,但不能在注释中验证
    • 好点。不过,我不确定他是否在使用 Automapper。