Data Validation
Client-side validation is being driven by these attributes. We ALSO get validation on the Server-side.
To turn client validation on/off:
<appSettings>
<add key=”ClientValidationEnabled” value= “true/false”/>
</appSettings>
There is also an HTML helper called EnableClientValidation(bool) that turns off client validation on a view by view basis. Now no validation happens on client but upon Submit, the Server sends back the errors.
- Required
- Regex - match string against
- Range
- StringLength
Custom Validation using a Custom Attribute
Good for packaging reusable validation logic- Create a new attribute class with ValidationAttribute as a base class
- Override the IsValid
- The framework will pass in a value to validate
- IsValid returns true or false
[AttributeUsage (AttributeTargets.Property)]
public sealed class MinLengthAttribute : ValidationAttribute
{
// ..
public override bool IsValid(object value)
{
string valueAsString = value As String;
return (valueAsString != null & valueAsString.Legth >= _minCharacters);
}
}
Self-Validating Model
Model itself is self-validating using IValidatableObject
public class Review : IValidatableObject
{
public virtual int ID {get; set}
...
[Required]
public virtual string Body {get; set;}
public virtual DateTime DiningDate {get; set;}
// impl IValidatableObject
public IEnumerable<ValidationResult>
Validate(ValidationContext validationContext)
{
if (ReviewDate > DateTime.Now)
{
yield return new ValidationResult(“Dinning date cannot be in the future”);
}
if (ReviewDate >DateTime.Now.AddYears(-1))
{
yield return new ValidationResult(“Dining date cannot be too far in the past”);
}
}
Validation attributes validation occurs first then this IValidatableObject occurs.
Error Display
Model-level errors appears at the top
in the ValidationSummary
ValidationResult needs to be associated with a
property to display it beside the property
Only the Model-level validation errors are shown in the ValidationSummary because:
@using (HtmlBeginForm()) {
@Html.ValidationSummary(true) // causes the summary display model-level errors only
<..
To display all errors in the summary: @Html.ValidationSummary(false)
To programmatically display error next to property:
var field = new [] {“DiningDate”};
if (DiningData > DateTime.Now)
{
yield return new ValidationResult(“Dinning date cannot be in the future”, field);
}
Display Format Annotations
- DisplayColumn - Specify the property of a model class for simple text display
- HiddenInput - Render value in hidden input (when editing)
- UIHint - Specify the name of the template to use for rendering
- DataType - Common templates (email, passoword, URL, currency, multiline)
- ReadOnly - Specify a read-only property (for model binding)
- DisplayFormat - Format strings and null display text. [DisplayFormat(DataFormatString={0:d”}, ApplyFormatInEditMode=true)] shows date portion only
- ScaffoldColumn - Turn off display and edit capabilities
- DisplayName - Friendly-name for labels. [DisplayName(“Score Date”) ]
// Model holds the data for a View and interacts with the backend
// May also contain data validation rules
using System.ComponentModel.DataAnnotations;
// FEATURES:
// Declarative Validation and Formatting using Data
// Annotation attributes
// Model Binder and Razor Views enforce these attributes
// Controller action: Call ModelState.IsValid
// Razor Views: Display errors using Html.ValidationMessaageFor
public class SomeClass
{
public int ID {get; set;}
[Required(ErrorMessage = "Customer Name is required")]
public string CustomerName {get; set;}
[Required(ErrorMessage = "Customer Since date is required")]
[DisplayFormat(DataFormatString = "{0:d}"]
public DateTime CustomerSince {get; set;}
[Required(ErrorMessage = "Credit limit must be entered")]
[Range(1, 1000, ErrorMessage="Credit limit must be between $1 and $1000")]
[DisplayFormat(DataFormatString = "{0:c}"]
public decimal CreditLimit {get; set;}
[StringLength(5)]
public string ZipCode {get; set;}
}