我正在.NET Core中使用FluentValidator。大多数情况下,一切都很顺利,但我注意到,在处理复杂类型时,FluentValidator会显示完整的属性名称。例如,假设我有一个名为Address的类,具有Street、City、State和Zip属性。现在假设我有一个由名为Physical Address的模型属性支持的表单。如果我需要街道,Fluent会显示以下验证错误:
'Physical Address. Street' must not be empty.
我更喜欢这样,而不是说";街道";不能为空,因为我可能在页面上有多个地址字段,所以只显示";街道";不够具体。但我宁愿说:
'Physical Address Street' must not be empty.
(字地址后无周期(
FluentValidation给出的全局覆盖显示名称的示例是将其添加到Startup.cs:中
ValidatorOptions.DisplayNameResolver = (type, member, expression) => {
if(member != null) {
return member.Name + "Foo";
}
return null;
};
覆盖示例有效,但使用它(减去foo部分(会显示以下验证错误:
'Street' must not be empty.
(正是我不想要的东西,因为它太通用了(
我需要知道的是lambda内部的逻辑会产生与默认行为完全相同的结果(即物理地址.Street,而不仅仅是街道(。一旦我知道了这一点,我就可以用一个简单的defaultValue.Replace(".","")
来修复删除句点的问题。谢谢
更新:
更简单的方法是使用ValidatorOptions.Global.PropertyNameResolver
ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, expression) =>
ValidatorOptions.Global.PropertyNameResolver(type, memberInfo, expression).SplitPascalCase();
原始答案:
准备了基于github源的完整演示
注意:我使用ValidatorOptions.Global.DisplayNameResolver
而不是ValidatorOptions.DisplayNameResolver
,因为它已经过时,将在未来的版本中删除
using FluentValidation;
using FluentValidation.Internal;
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApp4
{
public class Root
{
public PhysicalAddress PhysicalAddress { get; set; }
= new PhysicalAddress();
}
public class PhysicalAddress
{
public string Street { get; set; }
}
public class RootValidator : AbstractValidator<Root>
{
public RootValidator()
{
RuleFor(x => x.PhysicalAddress.Street).NotNull();
}
}
class Program
{
static string DefaultPropertyNameResolver(Type type, MemberInfo memberInfo, LambdaExpression expression)
{
if (expression != null)
{
var chain = PropertyChain.FromExpression(expression);
if (chain.Count > 0) return chain.ToString();
}
return memberInfo?.Name;
}
static void Main(string[] args)
{
ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, expression) =>
DefaultPropertyNameResolver(type, memberInfo, expression).SplitPascalCase();
var res = new RootValidator().Validate(new Root());
}
}
}