在Fluent Validation之前转换属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Fluent Validation之前转换属性相关的知识,希望对你有一定的参考价值。
在应用验证之前,我需要先转换我的属性(删除字符串上的空白)。
具体来说,我想检查一个字符串是否是一个枚举的一部分,但该字符串可能包含空格(据我所知,枚举不允许空格)。
就像...
RuleFor(x => x.Value).IsEnumName(typeof(EnumType))
(x.Value应该先去掉白格)
答案
FluentValidation方法 Transform
是针对这种情况设计的。下面使用的是Everson回答中的基本的空白去除器。
RuleFor(x => x.Value)
.Transform(x => x.Replace(" ", string.Empty))
.IsEnumName(typeof(EnumType));
我会选择一个更强的除白剂来处理标签等问题。
RuleFor(x => x.Value)
.Transform(x => new string(x.Where(c => !Char.IsWhiteSpace(c)).ToArray()))
.IsEnumName(typeof(EnumType));
不需要自定义验证器(例如......),而且我个人会避免编写一个验证器,除非没有其他方法。Must
),而且我个人会避免编写一个验证器,除非没有其他办法。
我会把那个空白去除器弹到一个扩展中(MVP,你应该处理null case;我更喜欢null guard,但那是另一个话题)。
public static class StringExtensions
public static string RemoveWhiteSpace(this string target)
return new string(target.Where(c => !Char.IsWhiteSpace(c)).ToArray());
这样规则就更容易读懂了。
RuleFor(x => x.Value)
.Transform(x => x?.RemoveWhiteSpace())
.IsEnumName(typeof(EnumType))
.When(x => x != null);
需要注意的地方。我发现,如果 Transform
返回 null
的 IsEnumName
规则会通过。我个人不喜欢这样,所以我会加入一条 When
规则构建器选项,只在 Value
或一个不为空的规则来确保它被提供。
工作的LINQPad示例。
public enum EnumType
Value1,
Value2,
Value3
public class Foo
public Guid Id get; set;
public string Value get; set;
public class FooValidator : AbstractValidator<Foo>
public FooValidator()
RuleFor(x => x.Value)
.Transform(x => x?.RemoveWhiteSpace())
.IsEnumName(typeof(EnumType));
.When(x => x != null);
public static class StringExtensions
public static string RemoveWhiteSpace(this string target)
return new string(target.Where(c => !Char.IsWhiteSpace(c)).ToArray());
void Main()
var validator = new FooValidator();
var foo1 = new Foo Id = Guid.NewGuid(), Value = "Value 1" ;
var result1 = validator.Validate(foo1);
Console.WriteLine(result1.IsValid);
var foo2 = new Foo Id = Guid.NewGuid(), Value = "Value2" ;
var result2 = validator.Validate(foo2);
Console.WriteLine(result2.IsValid);
var foo3 = new Foo Id = Guid.NewGuid(), Value = "Value 3" ;
var result3 = validator.Validate(foo3);
Console.WriteLine(result3.IsValid);
var foo4 = new Foo Id = Guid.NewGuid(), Value = "This is not a valid enum value" ;
var result4 = validator.Validate(foo4);
Console.WriteLine(result4.IsValid);
var foo5 = new Foo Id = Guid.NewGuid(), Value = null ;
var result5 = validator.Validate(foo5);
Console.WriteLine(result5.IsValid);
EDIT:
根据你的补充意见 将所有这些都打包成一个扩展,
public static class FluentValidationExtensions
public static IRuleBuilderOptions<T, string> IsEnumTypeMember<T>(this IRuleBuilderInitial<T, string> target)
return target
.Transform(x => x?.RemoveWhiteSpace())
.IsEnumName(typeof(EnumType))
.When(x => x != null);
然后更新规则来使用它
RuleFor(x => x.Value).IsEnumTypeMember();
这只是一个MVP,我并不知道你所有的用例;你可能想让它更通用,这样你就可以把它应用到其他枚举中。
另一答案
你可以使用一个自定义方法
RuleFor(x => x.Valor).Must(BeEnumType);
...
private bool BeEnumType(string v)
return Enum.IsDefined(typeof(EnumType), v.Replace(" ", string.Empty));
以上是关于在Fluent Validation之前转换属性的主要内容,如果未能解决你的问题,请参考以下文章