在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 返回 nullIsEnumName 规则会通过。我个人不喜欢这样,所以我会加入一条 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);

enter image description here

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之前转换属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fluent Validation 配置 NancyFx

使用 Fluent Validation 进行条件验证

Hypermesh画的网格怎样导入fluent

将枚举与自定义 Fluent 断言等效步骤进行比较

fluent编译UDF的过程中,出现了语法错误

在 Fluent 断言中排除未初始化 (null) 的属性