有没有办法使FluentValidation更动态?

时间:2019-02-08 13:50:04

标签: c# generics reflection fluentvalidation

我们刚刚从供应商处获得了第1阶段的发布,该版本将使用Angular 5将过时的PowerBuilder应用程序转换为C#MVC(我们已经有一个Angular的人已经在很大程度上重写了7中的前端,因此5中的安全性问题不再重要)。由于工作说明仅要求他们重现应用程序,因此对输入的验证几乎为零,因为原始应用程序的验证量很少(如果有的话)。

我最近对FluentValidation进行了一些研究,并喜欢它在以后使用相同整体数据的应用程序中的可重用性。但是,查看此代码后,MVC中的模型并未如可能的那样进行规范化,因此我们可以对数十种模型进行规范化,以便在数据字段(例如名字,姓氏,地址,营业地址等

我对泛型和反射有基本的经验,过去也支持一些更高级的示例。因此,我试图找到一种方法来利用这两个概念来使验证器更加动态。

除了与给定命名模型的基本硬连接之外,我无法找到更多更高级的FluentValidation示例的方式。我尝试使用通用T代替模型,但是无法弥合差距并访问传递给验证的对象。

 public class FormValidator : AbstractValidator<ModelExample>
 {
     public FormValidation()
     {

     }
 }   

//tried to do something like this but wasn't able to access the .HasProperties. Although I was able to access the GetProperties, 
//having trouble implementing it into the RuleFor however.
 public class FormValidation<T> : AbstractValidator<T>
{
    RuleFor(x => x.GetType().GetProperty(nameof({something if it exists}).{check stuff is valid}
{

public class ModelExample
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class OtherModelExample
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

我的最终目标是能够将相关对象传递到给定的验证器中,并且能够确定属性是否存在并采取相应的行动。

这可能是个问题,我真的不知道该如何在Google中问这个问题,我倾向于用措辞来表达我期望的方式。

这甚至可能是不可能的,但是如果它可以使我免于编写一系列硬耦合的验证器,而如果允许我们对数据流进行规范化的话,以后可能不得不重写它,将大有帮助。

>

任何具有比我发现的简单示例更高级的示例的文章或文档,即使在该项目之外,也将很有用。我发现的大多数教程都是非常基本的示例,有时我很难在“真实的”代码应用程序中将它们描绘出来。

谢谢

1 个答案:

答案 0 :(得分:1)

您不是考虑为整个模型创建通用验证器,而是为每个属性创建了相反的验证器吗?

如果使用custom property validators,则可以指定一次验证器逻辑,然后只需为每个视图模型创建一个验证器类。

例如:

class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Name = "Ada",
            NickName = "A"
        };
        var validator = new PersonValidator();
        var result = validator.Validate(person);

        //Should be a problem with the NickName
    }
}
class Person
{
    public string Name { get; set; }
    public string NickName { get; set; }
}

class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.Name).SetValidator(new NameValidator());
        RuleFor(x => x.NickName).SetValidator(new NameValidator());
    }
}

public class NameValidator : AbstractValidator<string>
{
    public NameValidator()
    {
        RuleFor(x => x).Must(x => x.Length > 1)
            .WithMessage("The name is not long enough");
    }
}

这也是一个更安全的选择,因为它是选择启用而不是隐式选择。