gpt4 book ai didi

c# - 验证正在抛出 "Unable to cast object of type ' BaseModel' 以键入 'DerivedModel'。”

转载 作者:行者123 更新时间:2023-11-30 22:55:15 24 4
gpt4 key购买 nike

当我尝试编写验证器时,我发现 FluentValidation (v8.2.0) 出现了一个奇怪的问题:

System.InvalidCastException HResult=0x80004002 Message=Unable to cast object of type 'BaseModel' to type 'DerivedModel'. Source=FluentValidation StackTrace: at FluentValidation.Internal.ConditionBuilder1.<>c__DisplayClass2_0.<When>g__Condition|0(ValidationContext context) in C:\Projects\FluentValidation\src\FluentValidation\Internal\ConditionBuilder.cs:line 62
at FluentValidation.Internal.PropertyRule.<Validate>d__67.MoveNext() in C:\Projects\FluentValidation\src\FluentValidation\Internal\PropertyRule.cs:line 270
at System.Linq.Enumerable.SelectManySingleSelectorIterator
2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator1.MoveNext()
at FluentValidation.AbstractValidator
1.Validate(ValidationContext`1 context) in C:\Projects\FluentValidation\src\FluentValidation\AbstractValidator.cs:line 115 at TestApp.Program.d__4.MoveNext() in C:\Users\john\Documents\Visual Studio 2017\Projects\TestApp\TestApp\Program.cs:line 76 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at TestApp.Program.(String[] args)

我的模型和验证器:

public class BaseModel
{
public string Name { get; set; }
public bool IsAlive { get; set; }
}

public class DerivedModel : BaseModel
{
public int Age { get; set; }
}

public class BaseModelValidator : AbstractValidator<BaseModel>
{
public BaseModelValidator()
{
RuleFor(o => o.Name).Length(1, 20);
}
}

public class DerivedModelValidator : AbstractValidator<DerivedModel>
{
public DerivedModelValidator(BaseModelValidator baseValidator)
{
foreach (var rule in baseValidator)
{
AddRule(rule);
}

RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
}
}

我使用的代码:

var baseModelValidator = new BaseModelValidator();
var derivedModelValidator = new DerivedModelValidator(baseModelValidator);

var baseModel = new BaseModel
{
IsAlive = true,
Name = "test2"
};
Console.WriteLine(baseModelValidator.Validate(baseModel).IsValid);

如您所见,我正在使用 BaseModelValidator验证 BaseModel ,并且此引用无处可寻 DerivedModel .

有趣的是,如果我删除行 var derivedModelValidator = new DerivedModelValidator(baseModelValidator); , 它可以正常工作。

是什么导致了这个异常,我该如何解决?

最佳答案

我实际上偶尔会在我的 Web 应用程序中看到这个问题 - 99% 的时间它都可以正常工作,但偶尔我会遇到这个问题。我 reached out致 FluentValidation 的作者 Jeremy Skinner,他解释了正在发生的事情:

Rules are intrinsicly tied to the validators that define them. They are not designed to be copied from one validator to another. They are inherently tied to the validator that defined them, and the type they were defined against.

Each condition block has a unique ID associated with it (that allows the result of the condition to be cached, so it's only executed one and not for each rule inside it). When you copy rules from one validator to another, the condition is brought across as well.

简而言之:您不能在验证器之间共享单个规则对象。

有问题的代码是 DerivedModelValidator 中的这个 block :

foreach (var rule in baseValidator)
{
AddRule(rule);
}

Jeremy 针对这个问题提供了两种不同的解决方案:

1。从包含共享规则的通用基本验证器类派生两个验证器类:

public abstract class CommonModelValidator<T> : AbstractValidator<T> where T : BaseModel
{
protected CommonModelValidator()
{
RuleFor(o => o.Name).Length(1, 20);
}
}

public class BaseModelValidator : CommonModelValidator<BaseModel>
{
}

public class DerivedModelValidator : CommonModelValidator<DerivedModel>
{
public DerivedModelValidator(BaseModelValidator baseValidator)
: base()
{
RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
}
}

2。使用 SetValidatorBaseModelValidator 组成 DerivedModelValidator:

public class BaseModelValidator : AbstractValidator<BaseModel>
{
public BaseModelValidator()
{
RuleFor(o => o.Name).Length(1, 20);
}
}

public class DerivedModelValidator : AbstractValidator<DerivedModel>
{
public DerivedModelValidator(BaseModelValidator baseValidator)
{
RuleFor(o => o).SetValidator(baseValidator);
RuleFor(o => o.Age).GreaterThanOrEqualTo(0);
}
}

关于c# - 验证正在抛出 "Unable to cast object of type ' BaseModel' 以键入 'DerivedModel'。”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55388890/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com