ASP.NET MVC3 условная проверка вложенности модели для EditorTemplate - PullRequest
3 голосов
/ 15 ноября 2011

Предположим, у вас есть viewModel:

public class CreatePersonViewModel
{
    [Required]
    public bool HasDeliveryAddress {get;set;}

    // Should only be validated when HasDeliveryAddress is true
    [RequiredIf("HasDeliveryAddress", true)]
    public Address Address { get; set; }
}

И модель Address будет выглядеть так:

public class Address : IValidatableObject
{
    [Required]
    public string City { get; set; }
    [Required]        
    public string HouseNr { get; set; }
    [Required]
    public string CountryCode { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string ZipCode { get; set; }
    [Required]
    public string Street { get; set; }

    #region IValidatableObject Members

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        string[] requiredFields;
        var results = new List<ValidationResult>();

        // some custom validations here (I removed them to keep it simple)

        return results;
    }

    #endregion
}

Кто-то предложил бы создать модель представления для Address и добавить туда некоторую пользовательскую логику, но мне нужен экземпляр Address, чтобы перейти к моему EditorTemplate для Address.

Основная проблема здесь заключается в том, что проверка адреса выполняется до проверки моей модели PersonViewModel, поэтому я не могу предотвратить ее.

Примечание: RequiredIfAttribute - это пользовательский атрибут, который делает то, что я хочу для простых типов.

Ответы [ 2 ]

7 голосов
/ 15 ноября 2011

Было бы несложно, если бы вы использовали FluentValidation.NET вместо DataAnnotations или IValidatableObject, которые довольно сильно ограничивают возможности проверки в сложных ситуациях:

public class CreatePersonViewModelValidator : AbstractValidator<CreatePersonViewModel>
{
    public CreatePersonViewModelValidator()
    {
        RuleFor(x => x.Address)
            .SetValidator(new AddressValidator())
            .When(x => x.HasDeliveryAddress);
    }
}
0 голосов
/ 15 ноября 2011

Simon Ince имеет альфа-версию Mvc.ValidationToolkit , которая, кажется, может делать то, что вы хотите.

Обновление
Насколько я понимаю, «проблема» заключается в классе DefaultModelBinder , который проверяет вашу модель на основе того, что, если он находит атрибут проверки, он спрашивает, является ли значение допустимым (на самом деле вполне разумно!), у него нет понятия иерархии. Для поддержки требуемой функциональности вам нужно написать пользовательское связующее для модели, которое связывает, а затем проверяет, если необходимо, как определено вашей декларативной разметкой.
Если вы пишете такой класс, он может быть хорошим кандидатом на фьючерсы MVC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...