Home

Form Validation

Vici MVC includes a very powerful and flexible validation mechanism for HTML forms. As shown in the section on forms, you can validate forms by three different mechanisms. You can combine all of these mechanisms to validate one single form.

Validation can happen by:

  • Validation attributes on fields
  • field validation methods for specific fields
  • Global form validation method for the complete form

Validation using attributes

On every field in a WebForm-derived class, you can specify validation attributes. The validation attributes available are:

  • [ValidateRequired]
  • [ValidateLength(minLength)]
  • [ValidateLength(minLength,maxLength)]
  • [ValidateRegex(regex)]
  • [ValidateRange(min,max)]
  • [ValidateExpression(expr)]

Most of these validation attributes don't need further explanation, except for the ValidateExpression attribute, which is explained below.

An important behavior of all validation attributes is that they will always be succesful if the field value is empty. For example, when you specify the attribute [ValidateLength(3)], the validation will succeed when nothing is filled in by the user, but will fail when just one character is filled in. To prevent this, you should add the [ValidateRequired] attribute.

The ValidateExpression attribute

The ValidateExpression attribute is a very powerful validator based on a custom validation expression. It allows you to specify an expression that evaluates to true or false (true meaning the validation was successful). The expression can be any C# expression returning a boolean value. All literals are supported like strings, numbers, booleans, etc. In addition, you can reference other fields of the form simply by using the field name in the expression. A special keyword this is available, which represents the field on which the attribute is defined.

Some examples:

public class SampleForm : WebForm
{
   [FormTextBox]
   public int MinimumPrice;
	
   [ValidateExpression("this > MinimumPrice")]
   [FormTextBox]
   public int MaximumPrice;
}

Validation using the field validation methods

On a WebForm-derived class, you can override the ValidateField() method. This method accepts 3 parameters: the field name being validated, the value of the field as entered by the user and an output parameter for returning an option error message. The return value should be false if validation fails. When the method returns true, the error message is ignored.

It's also possible to hook a specific validation function to specific fields by attaching an event handler to the specific field:

Fields["Name"].Validate += ValidateName;

The signature of the field validation event handler is:

bool ValidateField(string fieldName, object fieldValue, out string errorMessage);

Validation using the form validation method

To be completed

Validation error messages and CSS classes

When validation fails for a form, Vici MVC will render the invalid fields (controls) with a different CSS class. An explanation on how to specify CSS classes for controls can be found in the section on Form Basics.

In addition, the ViewData is automatically populated with two variables:

  • ValidationResult
  • ValidationErrors

The ValidationResult variable is an object containing information on the result of form validation. It can be used when rendering error messages to be presented to the user. The ValidationResult object has the following properties and methods:

Successtrue if there are no validation errors, false if there is at least one validation error.
MessagesA list of validation error messages. This list does not contain the error messages themselves, but objects with two properties "Message" and "ControlNames". "Message" contains the actual validation message, while "ControlNames" is a list of control names associated with this validation error message. This usually contains only one name, but you could have several controls that fail validation but generate the same error message. It would be pointless to show the same message twice, so Vici MVC solves this by returning only one error message, but linking it to more than one control (name)
ControlsA list of objects, one for each control that failed validation. The objects have two properties: "ControlName" and "Messages". "ControlName" is the name of the control, while "Messages" is a list of validation error messages associated with this control.
MessagesForControl(controlName)returns a list of all validation error messages for a specific control (name)
ControlsForMessage(message)returns a list of all control names for a specific validation message
HasErrors(controlName)returns true if the given control has any errors associated with it
HasMessages(controlName)returns true if the given control has any validation messages associated with it

Note that is perfectly valid to have validation error messages without associated controls, and to have invalid controls without associated validation messages.

Error messages will be translated by the framework, so validation error messages can contain localization tags.

Example:

<!--{{ if ValidationResult.Messages }}-->
<div class="ValidationSummary">
  <ul>
  <!--{{ foreach error in ValidationResult.Messages }}-->
    <li>{{ error.Message }}</li>
  <!--{{ endfor }}-->
  </ul>
</div>
<!--{{ endif }}-->

Note that we check for "ValidationResult.Messages". Since an empty message list will be evaluated as "false" by the view engine, this is the best way to write this.

What if we want to put a marker next to each field that has validation errors? Pretty easy:

<label>Name</label> [[Name]] <!--{{ if ValidationResult.HasErrors("Name") }}--> * <!--{{endif}}-->
<label>Login</label> [[Login]] <!--{{ if ValidationResult.HasErrors("Login") }}--> * <!--{{endif}}-->
<label>E-Mail</label> [[EMail]] <!--{{ if ValidationResult.HasErrors("EMail") }}--> * <!--{{endif}}-->

Automatic client side (Ajax) validation

Vici MVC has built-in support for validating forms using Ajax. This allows a far better user experience because the form won't have to be reloaded when a validation error occurs.

All you have to do is add the attribute [AjaxValidated] to your form class. Vici MVC will automatically create a javascript method $Mvc.ValidateForm() which you can call from client script. This method expects one parameter: a reference to the HTML form element containing the input fields you want to validate. The return value is an object of type "ValidationResult", which is the same object available inside the view template. The only restriction is that it only contains properties (no methods). The available properties are:

  • Success
  • Messages
  • Controls

For an example of these properties, check the section on Validation error messages.

An example on how to use ajax validation is included in the Vici MVC demo application.

Creating custom validation attributes

It is possible to create your own custom validation attributes that can be added to form fields. Simply create an attribute class derived from ValidationAttribute and override the Validate() method. The signature is:

protected bool Validate(object value, Type fieldType)

The fieldType parameter is the type of the associated field, but in most cases you won't need that. The value parameter is the value you want to validate. For example, this is the validate method of the ValidateLength attribute:

protected override bool Validate(object value, Type targetType)
{
   if (value == null || value.ToString().Length == 0)
     return true;

   int len = value.ToString().Trim().Length;

   return (len >= _min && len <= _max);
}

It is very important that the Validate() method returns true if the field value is empty. As exmplained earlier, empty fields are always valid, unless the [ValidateRequired] attribute is added to a field.