views:

47

answers:

2

Hi,

I have some problems with validation using Data Annotations in ASP.NET MVC 2. For example, I have Address class:

public class Address
{
    public long Id { get; set; }

    [Required]
    public string City { get; set; }

    [Required]
    public string PostalCode { get; set; }

    [Required]
    public string Street { get; set; }
}

And Order class:

public class Order
{
    public long Id { get; set; }

    public Address FirstAddress { get; set; }

    public Address SecondAddress { get; set; }

    public bool RequireSecondAddress { get; set; }
}

I want to validate Order.FirstAddress all the time, but Order.SecondAddress should be validated only if Order.RequireSecondAddress is set to true.

Any ideas? :)

Chris

+2  A: 

That's close to impossible using data annotations or it will require writing ugly code that relies on reflection, etc... (I think you get the point).

I would recommend you looking at the FluentValidation. It has a good integration with ASP.NET MVC. Here's how your validation logic might look like:

public class AddressValidator : AbstractValidator<Address>
{
    public AddressValidator()
    {
        RuleFor(x => x.City)
            .NotEmpty();
        RuleFor(x => x.PostalCode)
            .NotEmpty();
        RuleFor(x => x.Street)
            .NotEmpty();
    }
}

public class OrderValidator : AbstractValidator<Order>
{
    public OrderValidator()
    {
        RuleFor(x => x.FirstAddress)
            .SetValidator(new AddressValidator());
        RuleFor(x => x.SecondAddress)
            .SetValidator(new AddressValidator())
            .When(x => x.RequireSecondAddress);
    }
}

You will also benefit from having a separate validation layer which also could be unit tested in a very elegant way.

Darin Dimitrov
In FluentValidator there are some problems in the client-side with more complex validations, but I think this is not a big issue. Now I'm going to learn more about FluentValidator :) Thanks!
Chris
+1  A: 

Following conditional validation articles might help:

KMan
Thanks! That's what I've been looking for.
Chris