You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ASP.NET (Core)中验证后如何访问ValidationResult对象?

问题描述

我通过实现IValidatableObject接口为模型编写了自定义验证逻辑,代码如下:

public class MyModel : IValidatableObject 
{ 
    public string Name { get; set; } 
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
        if (Name == "Foo") 
        { 
            yield return new CustomValidationResult(42, nameof(Name)); 
        } 
    } 
} 

public class CustomValidationResult : ValidationResult 
{ 
    public CustomValidationResult(int bar, string memberName) : base("FooBar", new[] { memberName }) 
    { 
        Bar = bar; 
    } 
    public int Bar { get; private set; } 
}

现在我希望在控制器或者动作过滤器中访问CustomValidationResult对象,比如在下面这个动作过滤器里获取Bar属性的值(也就是42):

public class MyActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
        if (!context.ModelState.IsValid) 
        { 
            // 如何访问验证结果? 
            // 具体来说,如何在此处获取值'42'? 
        } 
    } 
}

请问有没有办法实现这个需求?

解决方案

当然可以实现!你需要遍历ModelState中的所有验证错误条目,然后将其中的ValidationResult实例强制转换为你的CustomValidationResult类型,就能拿到Bar属性的值了。

这里有两种常见的场景处理方式,直接上代码:

public class MyActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
        if (!context.ModelState.IsValid) 
        { 
            // 遍历所有ModelState条目及其错误
            foreach (var stateEntry in context.ModelState)
            {
                foreach (var error in stateEntry.Value.Errors)
                {
                    // 场景1:验证结果被包装在ValidationException中
                    if (error.Exception is ValidationException validationEx && 
                        validationEx.ValidationResult is CustomValidationResult customResult)
                    {
                        int targetValue = customResult.Bar; // 这里就是你要的42
                        // 后续可以根据这个值执行你的业务逻辑
                    }
                    // 场景2:验证结果直接作为ErrorInfo存在
                    else if (error.ErrorInfo is CustomValidationResult customResultFromInfo)
                    {
                        int targetValue = customResultFromInfo.Bar;
                    }
                }
            }
        }
    } 
}

如果你的验证逻辑只会针对特定字段(比如示例中的Name字段),也可以直接定向查找,不用遍历所有条目,效率更高:

public override void OnActionExecuting(ActionExecutingContext context) 
{ 
    if (!context.ModelState.IsValid) 
    {
        // 直接定位到Name字段的ModelState
        if (context.ModelState.TryGetValue(nameof(MyModel.Name), out var nameState))
        {
            foreach (var error in nameState.Errors)
            {
                if (error.ErrorInfo is CustomValidationResult customResult)
                {
                    int barValue = customResult.Bar;
                    // 处理你的逻辑
                }
            }
        }
    }
}

需要注意的是,不同的验证触发场景下,自定义验证结果的存储位置可能不同(要么在Exception里,要么在ErrorInfo里),所以两种情况最好都做判断,避免遗漏。

内容的提问来源于stack exchange,提问作者turdus-merula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:04:24