This is a simple example of standard MVC validation provided in the .NET framework.
Create a new MVC application.
Edit the index.cshtml file. Important: for client validation to work, the scripts section must be included. (Defined per default in the _Layout View and the BundleConfig.cs in the App_Start folder)
@model MvcStandardValidation.Models.HomeDataModel <h2>Validation Test for Standard MVC Validation</h2> @using (Html.BeginForm("Index", "Home")) { @Html.ValidationSummary(true) @Html.AntiForgeryToken() <fieldset> <legend>Validation Form</legend> <div> @Html.LabelFor(model => model.ValInt1) </div> <div> @Html.EditorFor(model => model.ValInt1) @Html.ValidationMessageFor(model => model.ValInt1) </div> <div> @Html.LabelFor(model => model.ValInt2) </div> <div> @Html.EditorFor(model => model.ValInt2) @Html.ValidationMessageFor(model => model.ValInt2) </div> <div> @Html.LabelFor(model => model.ValString1) </div> <div> @Html.EditorFor(model => model.ValString1) @Html.ValidationMessageFor(model => model.ValString1) </div> <div> @Html.LabelFor(model => model.ValString2) </div> <div> @Html.EditorFor(model => model.ValString2) @Html.ValidationMessageFor(model => model.ValString2) </div> <div> @Html.LabelFor(model => model.ValDouble1) </div> <div> @Html.EditorFor(model => model.ValDouble1) @Html.ValidationMessageFor(model => model.ValDouble1) </div> <div> @Html.LabelFor(model => model.ValDouble2) </div> <div> @Html.EditorFor(model => model.ValDouble2) @Html.ValidationMessageFor(model => model.ValDouble2) </div> <div> @Html.LabelFor(model => model.ValDateTime1) </div> <div> @Html.EditorFor(model => model.ValDateTime1) @Html.ValidationMessageFor(model => model.ValDateTime1) </div> <div> @Html.LabelFor(model => model.ValDateTime2) </div> <div> @Html.EditorFor(model => model.ValDateTime2) @Html.ValidationMessageFor(model => model.ValDateTime2) </div> <p> <input type="submit" value="SendToServer" /> </p> </fieldset> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
Create a Model
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; namespace MvcStandardValidation.Models { public class HomeDataModel { [Required] [Range(5,30)] public int ValInt1 { get; set; } public int? ValInt2 { get; set; } public string ValString1 { get; set; } [Required(ErrorMessage = "string2 is required")] public string ValString2 { get; set; } public double ValDouble1 { get; set; } public double? ValDouble2 { get; set; } public DateTime ValDateTime1 { get; set; } public DateTime? ValDateTime2 { get; set; } } }
Edit the web.config (for client side validation)
<appSettings> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings>
NOTE: The client validation can also be enabled/disabled per view:
@{ HtmlHelper.ClientValidationEnabled = false; HtmlHelper.UnobtrusiveJavaScriptEnabled = false; }
And here’s what your validation errors look like:
Because client validation is enabled, the model is validated on both the client and the server.
Extending the DataAnnotations Model Validator (Custom Validators)
The quickest way to create a custom validator is extend an existing one. This way client validation is supported without any extra effort.
Create an new Attribute
using System.ComponentModel.DataAnnotations; namespace MvcEL6Validation.Validators { [System.AttributeUsage(System.AttributeTargets.All, AllowMultiple = false, Inherited = true)] public sealed class CustomStringPatternAttribute : RegularExpressionAttribute { const string RegEx = "[0][0-9a-z]{5,20}"; public CustomStringPatternAttribute() : base(RegEx) { } } }
Add this to the required model
[CustomStringPattern] public string ValString1 { get; set; }
And extend the provider
using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using MvcEL6Validation.Validators; namespace MvcStandardValidation { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomStringPatternAttribute), typeof(RegularExpressionAttributeAdapter)); } } }
code: https://github.com/damienbod/MvcStandardValidation.git
Anthony Zigenbine provides a great post for property dependency. I have also included this in the example code as it is a great solution for this problem.
I’ve added his script to the validation bundles
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.unobtrusive*", "~/Scripts/jquery.validate*", "~/Scripts/RequiredIfValidation*"));
And the following files:
- RequiredIfAttribute.cs
- RequiredIfValidation.js
The model and the view are extended to include the requiredIf validator.
Links
http://anthonyvscode.com/2011/07/14/mvc-3-requiredif-validator-for-multiple-values/
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
http://www.codeproject.com/Articles/301022/Creating-Custom-Validation-Attribute-in-MVC-3