我正在处理此处找到的流畅验证文档。
https://docs. Fluidvalidation.net/en/latest/specific-properties.html#
在该文档中,有一个此类方法的示例。
_validator.Validate(this, v => v.IncludeProperties(propertyName));
简单 - 到目前为止一切顺利,除了当我在 Visual Studio 2022 中使用它时,我收到消息说没有可识别的方法来重载以选项操作作为第二个参数的验证。它是一个扩展方法,所以我希望 FluentValidation 中的某个地方有一个命名空间,我可以在代码顶部放置正确的 using 语句,以便编译器可以找到扩展方法,我挖啊挖啊挖……除了使用 FluentValidation 命名空间之外,文档中没有任何内容。
仍然不相信 - 我花了更多时间在 DotPeek 中查看 FluentValidation DLL,看看是否能在那里找到它,但什么也没找到。
如果我无法使用此方法,我将不得不转储流畅的验证,我需要能够控制在我的验证器上调用 Validate() 时验证哪些属性,但我真的很想保留它(但这确实是一个破坏因素 - 如果我被迫必须在验证调用上运行所有属性验证,那对我们来说是行不通的。
这是我尝试在 IValidate 上使用此验证重载时在 VS 中看到的屏幕截图
除了演示的地方之外,我试图在文档中找到任何有关扩展方法的提及。 我在 DotPeek 中反汇编了 DLL,以便进行流畅的验证,这样我就可以看到它是否在代码中的任何位置。 我尝试在代码文件顶部使用所有可用的命名空间进行 Fluent 验证。
我尝试升级,但不是这样,我有点怀疑这会是问题,因为 intellsense 可以找到它 - 所以它一定在那里。 知道在哪里查看是我的问题 - 我需要知道这个扩展是在哪里定义的,然后我尝试从静态中显式调用它,这样做让我知道哪里出了问题。
所以问题是我试图用这个实例调用 validate - 但在这种情况下这是一个通用的(基类实现)并且该方法被设计为可以从子类实现中的属性设置器调用。
我的班级就是这样定义的。
public abstract class ValidatableClientModelBase<TDto, TValidator, TModel> :
ClientModelBase<TDto,TModel>,
IDataErrorInfo
where TValidator : IValidator<TModel>
where TModel : ValidatableClientModelBase<TDto, TValidator, TModel>
所以我试图像这样流畅地将“this”传递给调用。
public bool ValidateProperty(string propertyName)
{
ValidationResult result = _validator.Validate(this, o =>
o.IncludeProperties(propertyName));
return result.IsValid;
}
问题在于扩展方法期望子类实例(我们所说的 TModel 泛型)是什么。这是一个从上面的类继承的子类的示例。
public sealed class TicketBed :
AuditableClientModelBase<Domain.Dto.TicketBed, ITicketBedValidator, TicketBed>,
ITicketBed
{ ...
在这个类中,我们在属性中使用上面定义的方法,如下所示。
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
MarkChanged();
ValidateProperty(nameof(Name));
OnPropertyChange(nameof(Name));
}
}
}
关键是将对此的引用转换为 TModel 泛型类型参数,原因是 IValidator 的泛型类型参数与我们的类型是协变的,因为我们的验证器是为该特定类 (TicketBed) 构建的 - 所以 AbstractValidator 会需要让 ValidateProperty 显式转换为 TModel(在本例中为 TicketBed),以便它可以识别由 AbstractValidator 验证的类型 - 隐式转换在这种情况下不起作用。
因此回到我的基类中告诉验证器验证属性的方法,我需要使用显式强制转换将其更改为以下内容。
public bool ValidateProperty(string propertyName)
{
ValidationResult result = _validator.Validate((TModel)this, o =>
o.IncludeProperties(propertyName));
return result.IsValid;
}
瞧!我们开始做生意了,世界一切都好起来了!
我被自己踩下的石头举了起来,哈哈!