I'm working with FluentValidator in .NET Core. Everything is working beautifully for the most part, but I notice that when working with complex types, FluentValidator shows the full property name. For example, let's say I have a class named Address with Street, City, State, and Zip properties. Now let's say I have a form backed by a model property named Physical Address. If I make the street required, Fluent shows the following validation error:
'Physical Address. Street' must not be empty.
I prefer this to it just saying "Street" must not be empty because I might have multiple address fields on the page, so just displaying "Street" isn't specific enough. But I'd rather have it say:
'Physical Address Street' must not be empty.
(with no period after the word address)
The example given by FluentValidation to globally override the display name is adding this in Startup.cs:
ValidatorOptions.DisplayNameResolver = (type, member, expression) => {
if(member != null) {
return member.Name + "Foo";
}
return null;
};
The override example works, but using this (minus the foo part) displays this validation error:
'Street' must not be empty.
(the very thing I don't want because it's too generic)
What I need to know is what logic inside the lambda would produce the exact same result as the default behavior (ie Physical Address. Street , not just Street ). Once I know that, I can fix removing the period with a simple defaultValue.Replace(".","")
. Thanks!
Update:
Much easier approach is to use ValidatorOptions.Global.PropertyNameResolver
ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, expression) =>
ValidatorOptions.Global.PropertyNameResolver(type, memberInfo, expression).SplitPascalCase();
Original Answer:
Prepared complete demo based on github sources
Note: I am using ValidatorOptions.Global.DisplayNameResolver
instead of ValidatorOptions.DisplayNameResolver
since it is obsolete and will be removed in future versions
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());
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.