开发者

Prevention of validating all of the properties of inner object in MVC

开发者 https://www.devze.com 2023-01-26 02:43 出处:网络
For example i have public class Person { public int Id {get;set;} [Required()] public string Name {get;set;}

For example i have

public class Person
{
    public int Id {get;set;}
    [Required()]
    public string Name {get;set;}
    [Required()]
    public Address Address {get;set;}
}

And

public class Address
{
    public int Id {get开发者_运维知识库;set;}
    [Required()]
    public string City {get;set;}
    [Required()]
    public string Street {get;set;}
}

I need to validate every property in Address, but when validating Person i need to validate only the id of Address. How to do that??


I don't know what do you mean by I need to validate every property in Address, but when validating Person i need to validate only the id of Address. Correct me if I am wrong but here's how I understand your question: you have two different controller actions:

[HttpPost]
public ActionResult ValidateAddress(Address address)
{
    ... // validate all properties of address
}

[HttpPost]
public ActionResult ValidatePerson(Person person)
{
    ... // validate only the Id of a person's Address
}

Well personally I would use FluentValidation instead of Data Annotations as it allows you to express your validation logic in a much cleaner way and among others handle cases like this one. So here's how this could be expressed in an elegant way:

/// <summary>
/// Validates all properties of an address
/// </summary>
public class AddressValidator : AbstractValidator<Address>
{
    public AddressValidator()
    {
        RuleFor(x => x.Id).NotEmpty();
        RuleFor(x => x.City).NotEmpty();
        RuleFor(x => x.Street).NotEmpty();
    }
}

/// <summary>
/// Validates only the id of an address
/// </summary>
public class PersonAddressValidator : AbstractValidator<Address>
{
    public PersonAddressValidator()
    {
        RuleFor(x => x.Id).NotEmpty();
    }
}

/// <summary>
/// Validates a Person
/// </summary>
public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.Name).NotEmpty();
        RuleFor(x => x.Address).SetValidator(new PersonAddressValidator());
    }
}

And your view model classes become simply:

[Validator(typeof(PersonValidator))]
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

[Validator(typeof(AddressValidator))]
public class Address
{
    public int Id { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
}

And your controller actions stay untouched except that they now behave as expected.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号