在C#winform应用程序中使用FluentValidation和自定义属性

时间:2015-12-11 00:32:51

标签: c# .net winforms fluentvalidation

我目前正在开发一个链接到数据库的应用程序,但它不使用EntityFramework来生成数据库对象。相反,我创建了处理实体的自定义类。这些实体中的字段也使用自定义类。这是一个简单的例子:

public class BookEntity : Entity
{
    public Field BookId {get; set;}
    public Field Name {get; set;}
    public Field Page {get; set;}

    public BookEntity()
    {
        BookId = new Field("Books_BookId");
        Name = new Field("Books_Name");
        Page = new Field("Books_Page");
    }
}

public class Field
{
    public String Viewfield{get; set;}
    public Object Value{get; set;}
}

如您所见,我的Field类包含两个属性。第一个包含字段的名称(使用Tablename),另一个是值。

我的问题是使用FluentValidation,我希望能够将返回的属性名称设置为Viewfield属性。我目前可以使用WithState扩展程序执行此操作,但是我需要在每个流畅的验证规则中指定它。

private class BookValidator : AbstractValidator<Book>
{
    /// <summary>
    /// Constructor that contains all the validation rules
    /// </summary>
    public BookValidator()
    {
        RuleFor(p => (Double?)p.Page.Value)
            .NotNull().WithState(p => p.Page.Viewfield)
            .LessThanOrEqualTo(p => 1000).WithState(p => p.Page.Viewfield)
            .GreaterThanOrEqualTo(p =>100).WithState(p => p.Page.Viewfield)
    }
}

我确实尝试使用PropertyNameResolver,但由于我无法在解析器中访问Book实例,因此无法访问Viewfield属性。

我希望能够避免重复使用WithState。

另请注意,我无法在字段中使用自定义属性来设置Viewfield

我希望自己做得很好解释,

感谢。

1 个答案:

答案 0 :(得分:0)

我不知道FluentValidation,但我认为你的实现真的太奇怪了,不支持,也许FluentValidation有某种可插拔的机制来获取你可以挂钩的属性值,但我怀疑......无论如何奇怪的是奇怪(顺便说一下,这真的很奇怪:D),你可以将所有FluentAPI包装到你自己的扩展中,比如NotNullEx,LessThanOrEqualToEx等......

这些扩展只需要使一个参数更加尊重相应的FluentAPI,然后在该扩展中调用FluentValidation验证器并返回其结果,这样您就可以链接并保持语法流畅

e.g。

RuleFor(p => (Double?)p.Page.Value)
        .NotNull().WithState(p => p.Page.Viewfield)

可能会成为

RuleFor(p => (Double?)p.Page.Value)
        .NotNullEx(p => p.Page.Viewfield)

这对你没有多大帮助,因为你无论如何都需要指定linq选择器(如果你让扩展接受一个字符串来选择属性名称,则为直接参数值)

另一种方法是创建自己的验证器继承自原始验证器并将它们挂钩到FluentValidator,无论如何你应该通过该属性值,所以我认为它不是完美的解决方案

更新: 在这里阅读WithState扩展https://github.com/JeremySkinner/FluentValidation/blob/c101786a923406acff6029b00f664a91a097a9af/src/FluentValidation/DefaultValidatorOptions.cs在我看来,你可以在RuleFor(...)之后调用WithState而不是每个验证行

所以而不是

RuleFor(p => (Double?)p.Page.Value)
   .NotNull().WithState(p => p.Page.Viewfield)
   .LessThanOrEqualTo(p => 1000).WithState(p => p.Page.Viewfield)
   .GreaterThanOrEqualTo(p =>100).WithState(p => p.Page.Viewfield)

你可以试试

RuleFor(p => (Double?)p.Page.Value)
   .NotNull()
   .WithState(p => p.Page.Viewfield)
   .LessThanOrEqualTo(p => 1000)
   .GreaterThanOrEqualTo(p =>100)

这有效吗?

相关问题