流利验证之前转换属性

用户

在应用验证之前,我需要先转换我的属性(删除字符串上的空白)。

具体来说,我想检查字符串是否是枚举的一部分,但字符串可能包含空格(据我所知,枚举不允许这样)

就像是...

RuleFor(x => x.Value).IsEnumName(typeof(EnumType)) 

(x.Value应该先删除空格)

g

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,您应该处理空值;我的偏好是空值保护,但这是另一个主题):

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);
}

在此处输入图片说明

编辑:

根据您有关将所有这些都包装到扩展中的其他注释:

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,我真的不知道您的所有用例。您可能希望使其更通用,以便将其应用于其他枚举。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章