Проверка сущности с другим сценарием - PullRequest
0 голосов
/ 23 июня 2009

Предполагается, что у меня есть Entity с парой полей. Некоторые поля обязательны для заполнения в определенном состоянии, а другие - только для дальнейшего / другого состояния.

public class Entity
{
    //Required always
    public SomeReference {}

    //Required in specific situation/scenario
    public OtherReference {}
}

Как достичь этого сценария с какой-то известной платформой валидации или как сделать это самостоятельно?

Для справки: У Уди Дахана есть некоторые мысли по этому поводу. http://www.udidahan.com/2007/04/30/generic-validation/

Ответы [ 2 ]

1 голос
/ 21 декабря 2009

У меня есть решение, которое я использую в данный момент. Я использую Свободное подтверждение и все еще привыкаю к ​​нему. Я могу привести пример простого сценария, который у меня есть. возможно это поможет. У меня есть пользовательский класс, со свойством адрес объекта. В какой-то момент я хочу проверить только данные пользователя (имя, адрес электронной почты, пароль и т. Д.), А в другом состоянии я хочу проверить адрес пользователя (первая строка, почтовый индекс и т. Д.).

Классы выглядят так:

public class User {
    public virtual string Name { get; set; }
    public virtual string Email { get; set; }
    public virtual string Password { get; set; }
    public virtual Address Address { get; set; }        
}

public class Address {
    public virtual string Address1 { get; set; }
    public virtual string PostCode { get; set; }
}

У меня есть два (упрощенных) валидатора, один для адреса и один для пользователя:

    public AddressValidator() {
        RuleFor(address => address.Address1)
            .NotNull()
            .WithMessage("Please enter the first line of your address");

        RuleFor(address => address.PostCode)
            .NotNull()
            .WithMessage("Please enter your postcode")
            .Matches(UK_POSTCODE_REGEX)
            .WithMessage("Please enter a valid post code!");
    }

    public UserValidator() {
        RuleFor(user => user.FirstName)
            .NotNull()
            .WithMessage("Please provide a first name")
            .Length(3, 50)
            .WithMessage("First name too short");

        RuleFor(user=> user.Password)
            .Length(8, 50)
            .WithMessage("Password is too short");
    }

Затем я создаю Валидатор модели, например, скажем, у нас есть форма, в которую пользователь вводит адрес, мы создаем AddressModelValidator и можем повторно использовать написанные нами валидаторы:

    public AddressModelValidator()  {
        RuleFor(user => user.id)
            .NotNull()
            .WithMessage("An error has occured, please go back and try again");

        RuleFor(user => user.Address).SetValidator(new AddressValidator());
    }

Итак, подумав, вы действительно можете создать несколько хороших моделей и уменьшить дублирование кода проверки!

0 голосов
/ 23 июня 2009

Я предпочитаю локализовать общие функции проверки, такие как проверка электронной почты и даты, в классе ValidationService, в который я могу передать свой объект. В остальном же я склоняюсь к валидации самого класса. Если я использую LINQ to SQL, я могу создать метод Validate () для моего объекта, который LINQ to SQL будет вызывать перед сохранением объекта в БД, например:

public void Validate()
{
    if(!IsValid)
        throw new ValidationException("Rule violations prevent saving");
}

public bool IsValid
{
    get { return GetRuleViolations().Count() == 0;}
}

public IEnumerable<RuleViolation> GetRuleViolations()
{
    if(this.TermID == 0)
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(1), "agreeWithTerms");

    if(ValidationService.ValidateDate(this.Birthdate.ToString()))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(2), "birthDate");

    if (!(Username.Length >= ConfigurationService.GetMinimumUsernameLength()) ||
        !(Username.Length <= ConfigurationService.GetMaximumUsernameLength()))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(5), "username");

    if(ValidationService.ValidateUsernameComplexity(Username))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(6), "username");

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().UsernameExists(this.Username))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(7), "username");

    if (!ValidationService.ValidateEmail(Email))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(8), "email");

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().EmailExists(this.Email))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(9), "email");

    yield break;
}

Прочитайте здесь для полного понимания этого: http://nerddinnerbook.s3.amazonaws.com/Part3.htm

...