Understand the Html generated by the unobtrusive validation in Asp.net MVC

this is part of “understanding Asp.net Mvc Unobtrusive Validation” series

  1. How the jQuery validate plugin works internally
  2. Understand the Html generated by the unobtrusive validation in Asp.net MVC
  3. How the unobtrusive jQuery validate plugin works internally in Asp.net MVC

What we will be talking about in this article

The idea of unobtrusive JavaScript

Microsoft released its validation module from the first version of Mvc but it has really matured in every version until finally the release of unobtrusive validation in Asp.net Mvc 3

In short even writing modern JavaScript, which is basically JavaScript in a separate js file. we sometimes need data associated with the Html so we write some metadata JavaScript objects inside the Html page itself and will call a function from the external js file passing it the metadata object in the page

one of the goals of unobtrusive JavaScript is to separate JavaScript from Html markup

To read more about this subject check this article


Difference between normal and unobtrusive validation

We now will see a Model and the corresponding Html generated using MVC 2 and MVC 3 using unobtrusive validation

Our Model

public class ValidationModel {
  [Required]
  public string FirstName { get; set; }

  [Required, StringLength(60)]
  public string LastName { get; set; }

  [Range(1, 130)]
  public int Age { get; set; }
}

The View in MVC 2 using html helpers

<label for="FirstName">FirstName</label>
<input id="FirstName" class="text-box single-line" type="text" name="FirstName" value="" />
<span id="FirstName_validationMessage" class="field-validation-valid"></span>

<label for="LastName">LastName</label>
<input id="LastName" class="text-box single-line" type="text" name="LastName" value="" />
<span id="LastName_validationMessage" class="field-validation-valid"></span>

<label for="Age">Age</label>
<input id="Age" class="text-box single-line" type="text" name="Age" value="" />
<span id="Age_validationMessage" class="field-validation-valid"></span>

<script type="text/javascript">// <![CDATA[
if (!window.mvcClientValidationMetadata) { window.mvcClientValidationMetadata = []; } window.mvcClientValidationMetadata.push({"Fields":[{"FieldName":"FirstName","ReplaceValidationMessageContents":true,"ValidationMessageId":"FirstName_validationMessage","ValidationRules":[{"ErrorMessage":"The FirstName field is required.","ValidationParameters":{},"ValidationType":"required"}]},{"FieldName":"LastName","ReplaceValidationMessageContents":true,"ValidationMessageId":"LastName_validationMessage","ValidationRules":[{"ErrorMessage":"The LastName field is required.","ValidationParameters":{},"ValidationType":"required"},{"ErrorMessage":"The field LastName must be a string with a maximum length of 60.","ValidationParameters":{"max":60},"ValidationType":"length"}]},{"FieldName":"Age","ReplaceValidationMessageContents":true,"ValidationMessageId":"Age_validationMessage","ValidationRules":[{"ErrorMessage":"The field Age must be between 1 and 130.","ValidationParameters":{"min":1,"max":130},"ValidationType":"range"},{"ErrorMessage":"The Age field is required.","ValidationParameters":{},"ValidationType":"required"},{"ErrorMessage":"The field Age must be a number.","ValidationParameters":{},"ValidationType":"number"}]}],"FormId":"form0","ReplaceValidationSummary":true,"ValidationSummaryId":"validationSummary"});
// ]]></script>

The View in MVC 3 using html helpers & unobtrusive validation

<label for="FirstName">FirstName</label>
<input id="FirstName" class="text-box single-line" type="text" name="FirstName" value="" data-val="true" data-val-required="The FirstName field is required." />

<label for="LastName">LastName</label>
<input id="LastName" class="text-box single-line" type="text" name="LastName" value="" data-val="true" data-val-length="The field LastName must be a string with a maximum length of 60." data-val-length-max="60" data-val-required="The LastName field is required." />

<label for="Age">Age</label>
<input id="Age" class="text-box single-line" type="text" name="Age" value="" data-val="true" data-val-number="The field Age must be a number." data-val-range="The field Age must be between 1 and 130." data-val-range-max="130" data-val-range-min="1" data-val-required="The Age field is required." />

this code was taken from Brad Wilson article

As we can see the Html inputs generated from MVC 2 don’t have any knowledge about what kind of validation rules that are applied to them.
There is only a big JavaScript object containing all the info of the validation applied to every element on this page

On the other hand if we look at the inputs generated with MVC 3 it looks like they have much more metadata info in them and this is all the info needed for validating these fields in a from of data-* attributes and there is no need for a big JavaScript object

<!-- Input generated using MVC2 -->
<input id="FirstName" class="text-box single-line" type="text" name="FirstName" value="" />

<!-- Input generated using MVC3 -->
<input id="FirstName" class="text-box single-line" type="text" name="FirstName" value="" data-val="true" data-val-required="The FirstName field is required." />

Understanding Unobtrusive validation

1-Inputs and their validation rules and how they work

so lets explain what happens with these data-* attributes

  • MVC outputs the data-* attributes based on the validation rules
  • jquery.validate.unobtrusive will read these rules and translate them in a way
  • after the unobtrusive validation translates these rules it will call validate() method and pass the rules array with other options to validate it

there are three parts of any unobtrusive rule in any Html element

  • The data-val=”true” its just a flag that this element has unobtrusive validation attached to it
  • The data-val-rulename=”message” it does two things first it declares that this element has a rule which is the data-val-rulename and the other is the error message which is the value of it
  • The data-val-rulename-additionalvalues=”value” this for adding additional values required by the validation rule to complete its validation (Ex. a range validation that must be more than a value and less than a value)

we can take a closer look at a generated input and explain these data-* attributes

<input id="Name" class="ignore" type="text" name="Name" value="" data-val="true" data-val-required="*" data-val-atleastonerequired="Enter at least Name, Email or Lastname" data-val-atleastonerequired-attributes="Email,LName" />

there are two rules attached to this element
one is the built in required attribute and the other is a custom one called atleastonerequired
and when the user doesn’t enter any data and press submit a * will appear as the validation message indicating the element is required and if the user violated the atleastonerequired its validation message would appear instead

2-The validation messages and how they work in the unobtrusive validation

Lets start with an example and build from there

<!-- Required input using unobtrusive validation -->
<input id="FirstName" class="text-box single-line" type="text" name="FirstName" value="" data-val="true" data-val-required="The FirstName field is required." />

<!-- The input's validation message placeholder -->
<span data-valmsg-replace="true" data-valmsg-for="Name" class="field-validation-valid help-inline" />

As we can see there are two data-* on the validation placeholder

  • “data-valmsg-for” its value is the input’s name attribute that this placeholder belongs to , the input & placeholder must be in the same form tag
  • “data-valmsg-replace” its true by default the difference between true and false , true will change the text of the placeholder depending on what validation rule was violated if its false it will be static and the content won’t change only the class name will switch on valid and invalid

if there is violation of any of the rules there will be a class name of “field-validation-error” and if there is none the class name will be “field-validation-valid”

About these ads

2 thoughts on “Understand the Html generated by the unobtrusive validation in Asp.net MVC

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