MVC 4.0: CUSTOM VALIDATION LOGIC

The extensibility of the ASP.NET MVC framework means an infinite number of possibilities exist for implementing custom validation logic. However, this post focuses on two core scenarios:

  • Packaging validation logic into a custom data annotation
  • Packaging validation logic into a model object itself

Custom Annotations

Imagine you want to restrict the last name value of a customer to a limited number of words. For example, you might say that 10 words are too many for a last name.

    public class MaxWordsAttribute : ValidationAttribute
    {
        public MaxWordsAttribute(int maxWords)
            :base("{0} has too many words.")
        {
            _maxWords = maxWords;
        }

        protected override ValidationResult IsValid(
            object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                var valueAsString = value.ToString();
                if (valueAsString.Split(' ').Length > _maxWords)
                {
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
            }
            return ValidationResult.Success;
        }

        private readonly int _maxWords;
    }

With the validation logic in place, you can apply the attribute to any model property:

    [Required]
    [StringLength(160)]
    [MaxWords(10, ErrorMessage="There are too many words in {0}")]
    public string LastName { get; set; }

Now if the customer types in too many words, he’ll see the message in the following figure in the view.
maxwords validation

IValidatableObject

A self-validating model is a model object that knows how to validate itself. A model object can announce this capability by implementing the IValidatableObject interface.

    public class Order : IValidatableObject
    {
        public IEnumerable<ValidationResult> Validate(
        ValidationContext validationContext)
        {
            if (LastName != null &&
            LastName.Split(' ').Length > 10)
            {
                yield return new ValidationResult("The last name has too many words!",
                new[] { "LastName" });
            }
        }
        // rest of Order implementation and properties
        // ...
    }

This has a few notable differences from the attribute version.

  • The method the MVC run time calls to perform validation is named Validate instead of IsValid, but more important, the return type and parameters are different.
  • The return type for Validate is an IEnumerable instead of a single ValidationResult, because the logic inside is ostensibly validating the entire model and might need to return more than a single validation error.
  • There is no value parameter passed to Validate because you are inside an instance method of the model and can refer to the property values directly.

Many validation scenarios are easier to implement using the IValidatableObject approach, particularly scenarios where the code needs to compare multiple properties on the model to make a validation decision.

Thank you,
Keep It Simple and Straightforward 🙂
~:H}{H:~

Advertisements

3 thoughts on “MVC 4.0: CUSTOM VALIDATION LOGIC

  1. […] talked about CUSTOM VALIDATION LOGIC  and we saw how to implement custom validation logic to our model […]

  2. […] talked about CUSTOM VALIDATION LOGIC  and we saw how to implement custom validation logic to our model […]

  3. “MVC 4.0: CUSTOM VALIDATION LOGIC Hossam Hassan” honestly got me simply
    hooked with your site! I reallywill probably be back a whole lot more regularly.
    Thank you -Sung

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s