Есть ли способ сделать FluentValidation более динамичным? - PullRequest
0 голосов
/ 08 февраля 2019

Мы только что получили релиз фазы 1 от поставщика, чтобы перевести архаичное приложение PowerBuilder в C # MVC с Angular 5 (у нас есть 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 голосов
/ 08 февраля 2019

Вместо того, чтобы создавать общие валидаторы для всей модели, вы рассматривали обратное и создавали ли они их для каждого свойства?

Если вы используете пользовательских валидаторов свойств , вы можете указать логику валидатора один раз, а затем просто создайте класс валидатора для модели представления.

например:

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

Возможно, это также более безопасный вариант, так как он включен, а не скрыт.

...