Tutorial :Entity validation with different scenario


On the assumption that I have Entity with couple of fields. Some fields are required at some specific state but others only on further/other state.

public class Entity  {      //Required always      public SomeReference {}        //Required in specific situation/scenario      public OtherReference {}  }  

How to achieve that scenario with some known validation framework or how to do it by my self?

For help: Udi Dahan has some thoughts on this. http://www.udidahan.com/2007/04/30/generic-validation/


I have a solution that I am using at the moment. I use Fluent validation and am still getting used to it. I can give you an example of a simple scenario I have. maybe it helps. I have a user class, with a address Object property. At some point, I want to only validate the User details(name, email, password, etc) and at another state I want to validate the user address(first line, postcode, etc).

Classes look like this:

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

I then have two (simplfied) validators, one for an address and one for a user:

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

I then create a Model Validator, so for example, say we have a form where the user enters an address, we create a AddressModelValidator, and can re-use the validators we have written:

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

So, with some thought, you can really create some nice models, and reduce your validation code duplication!


My preferernce is to localize common validation functions such as email and date validations into a ValidationService class that I can pass my object into. For the rest though I tend to put the validation into the class itself. If I am using LINQ to SQL then I can create a Validate() method on my object which LINQ to SQL will call prior to saving the object to the db like this:

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

Read here for a full understanding of this: http://nerddinnerbook.s3.amazonaws.com/Part3.htm

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »