C# 如何创建带有特定验证错误消息的自定义FluentValidation PropertyValidator?

C# 如何创建带有特定验证错误消息的自定义FluentValidation PropertyValidator?,c#,validation,fluentvalidation,C#,Validation,Fluentvalidation,我有几个不同的类,其名称属性的类型为string,但在每种情况下验证名称的规则都是相同的,例如,不得为null,介于1到32个字符之间,不得包含某些无效/符号字符等-您明白了 我正在使用FluentValidation库进行验证。我对它很陌生,但就像我到目前为止看到的一样。我首先为对象模型中的每个类创建AbstractValidator派生的验证类,以验证它们的属性。我很快意识到我在复制代码来验证各种类的名称属性,因此决定创建一个namevalidater自定义属性验证器(即自定义Propert

我有几个不同的类,其名称属性的类型为
string
,但在每种情况下验证名称的规则都是相同的,例如,不得为null,介于1到32个字符之间,不得包含某些无效/符号字符等-您明白了

我正在使用FluentValidation库进行验证。我对它很陌生,但就像我到目前为止看到的一样。我首先为对象模型中的每个类创建
AbstractValidator
派生的验证类,以验证它们的属性。我很快意识到我在复制代码来验证各种类的名称属性,因此决定创建一个
namevalidater
自定义属性验证器(即自定义
PropertyValidator
派生类)。其目的是将四到五条重复的名称验证逻辑封装在一个地方

但是,我不喜欢这个解决方案(基于我的新手理解),因为必须在构造函数中定义错误消息并将其传递给基类,所以我不能根据验证失败的条件指定不同的、特定的验证错误消息。换句话说,验证错误消息绑定到类类型,而不是
IsValid(…)
override中的运行时逻辑。例如,如果名称太长,我想提供一条特定的消息,这样说,而不是一条复合消息,说验证失败的原因有十几个,让用户找出谁是真正的罪魁祸首。也许这在某种程度上是可能的,而我只是错过了它,或者也许属性验证器根本不打算支持多种验证类型的概念

我考虑的下一种方法是创建一个
NameValidator
类,该类派生自
AbstractValidator
,并使用各种
RuleFor
语句,其形式为:
RuleFor(name=>name).Foo(…)
等,这有助于定义特定的验证错误消息。但是,这种“感觉是错误的”,因为
AbstractValidator
用于验证对象,而
PropertyValidator
用于验证属性。如对该方法的有效性(或其他方面)有任何想法/建议,将不胜感激


因此,我的问题是,建议使用FluentValidation库以可重用的方式将各种属性验证逻辑封装在一起,同时保持提供精确描述验证失败原因的特定验证错误消息的能力。如果是我,我将使用
NameValidator:AbstractValidator
方法。
Name
符合太多的要求,这一事实使它本身成为了一个对象


同样在语义上,
PropertyValidator
用于表示单一类型的约束,而不是对象的单一属性

感谢Raj的合理回答。我同意你的推理。然而,自从使用
AbstractValidator
方法以来,我注意到了两个不幸的副作用。一个是,
ValidationFailure.PropertyName
中的返回值现在是“Name.Name”,而不仅仅是“Name”。另一种情况是,
NotNull
内置验证器不再工作(但其他验证器工作,例如,
Length
)。这让我担心这种方法可能会带来其他未知和意外的后果。我刚刚在GitHub FluentValidation项目页面上遇到了一个密切相关的问题/答案:。Jeremy Skinner(FluentValidation库的作者/架构师)基本上说,不建议创建
AbstractValidator
,因为它存在已知的问题,所以我最初的问题仍然存在。基本上,问题只存在于基元类型中。所以,如果您要创建一个类名——其中包含一个字符串——那么您可以使用AbstractValidator。你尝试过这个方法吗?我确实考虑了这个方法,但是在你的域模型中创建新的类只是为了适应验证库,似乎有点费力/费解。那好像是尾巴在摇狗!不过,我可以继续采用这种方法。谢谢你的创造性思维,我真的很感激!就我个人而言,我也不太喜欢这种方法。我最喜欢的方法就是我的答案。只有它不能被使用。然而在目前的情况下,我会优先考虑时间而不是漂亮的代码。若它有效且不直观,那个么我将添加一条注释进行解释,并转到下一个问题