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

升级Fluent Validation至9.2.2后遇IValidationContext无CloneForChildValidator定义错误求助

解决FluentValidation升级后CloneForChildValidator不存在的问题

FluentValidation 9.x版本重构了验证上下文的创建逻辑,移除了IValidationContext上的CloneForChildValidator方法,需要改用新方式创建子验证上下文。以下是修改后的PolymorphicValidator代码:

public class PolymorphicValidator<TBaseClass> : NoopPropertyValidator
    where TBaseClass : class
{
    private readonly Dictionary<Type, IValidator> _derivedValidators = new Dictionary<Type, IValidator>();

    public PolymorphicValidator<TBaseClass> Add<TDerived>(IValidator<TDerived> derivedValidator) where TDerived : TBaseClass
    {
        _derivedValidators[typeof(TDerived)] = derivedValidator;
        return this;
    }

    public override IEnumerable<ValidationFailure> Validate(PropertyValidatorContext context)
    {
        // 补充集合类型验证逻辑(可根据实际需求调整)
        var collection = context.PropertyValue as IEnumerable<TBaseClass>;
        if (collection == null) yield break;

        int index = 0;
        foreach (var item in collection)
        {
            if (item != null)
            {
                foreach (var failure in ValidateType(item, context, index))
                {
                    yield return failure;
                }
            }
            index++;
        }
    }

    private IEnumerable<ValidationFailure> ValidateType(TBaseClass item, PropertyValidatorContext context, int index)
    {
        var actualType = item.GetType();
        if (_derivedValidators.TryGetValue(actualType, out var derivedValidator))
        {
            // 将父上下文转换为具体的ValidationContext类型
            var parentContext = context.ParentContext as ValidationContext;
            if (parentContext == null)
            {
                return Enumerable.Empty<ValidationFailure>();
            }

            // 创建新的子验证上下文,复制父上下文的核心属性
            var newContext = new ValidationContext(
                item, 
                parentContext.PropertyChain.Clone(), 
                parentContext.Selector
            );

            // 复制父上下文的RootContextData,保证上下文数据传递
            foreach (var kvp in parentContext.RootContextData)
            {
                newContext.RootContextData[kvp.Key] = kvp.Value;
            }

            // 添加当前属性名和索引到属性链
            newContext.PropertyChain.Add(context.Rule.PropertyName);
            newContext.PropertyChain.AddIndexer(index);

            return derivedValidator.Validate(newContext).Errors;
        }
        return Enumerable.Empty<ValidationFailure>();
    }
}

修改说明

  1. 替换上下文创建逻辑:不再调用CloneForChildValidator,直接实例化ValidationContext,传入子验证对象、克隆后的父属性链和选择器。
  2. 保留上下文数据:手动复制父上下文的RootContextData,确保验证过程中的上下文数据能正确传递。
  3. 完善核心验证逻辑:补充了集合类型遍历验证的示例(可根据实际业务场景调整)。

内容的提问来源于stack exchange,提问作者F sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:42:37