There are a lot of articles about validation in MVC. I’ve tried all of them and tried to find optimal and nice solution to validate model defined with Entity Framework, using Data Annotation attributes and have client-side validation related to these attributes using jQuery validation plugin. Too much? :) I don’t think so. Here is the solution.
Let’s say we have table and entity class in our DB model for this table
And we want to add validation for create action form. First we should create partial class for entity with data annotation attributes. But standard annotation attributes are not acceptable because they will work only with Microsoft AJAX validation library. For jQuery validation plugin, look at the project "jQuery Data Annotations". I modified this project to ignore metadata in entity model (You can download it from here). Using this "jQuery Data Annotations":
/// MapMarker.cs using System; using System.Web.Mvc; using jQuery.Validation.DataAnnotations; using System.ComponentModel.DataAnnotations; namespace Kitsula.Models.DAL { [MetadataType(typeof(MapMarkerMetaData))] public partial class MapMarker { [Bind(Exclude="Id")] public class MapMarkerMetaData { [jQuery.Validation.DataAnnotations.Required(ErrorMessage="Date required")] [jQuery.Validation.DataAnnotations.Date] public DateTime Date { get; set; } [jQuery.Validation.DataAnnotations.Required(ErrorMessage="Title required")] [jQuery.Validation.DataAnnotations.MaxLength(250, ErrorMessage="Must be under 250 characters")] public string Title { get; set; } [jQuery.Validation.DataAnnotations.Required(ErrorMessage="Latitude required")] [jQuery.Validation.DataAnnotations.Number] public decimal Lat { get; set; } [jQuery.Validation.DataAnnotations.Required(ErrorMessage="Longitude required")] [jQuery.Validation.DataAnnotations.Number] public decimal Lng { get; set; } [jQuery.Validation.DataAnnotations.MaxLength(150, ErrorMessage="Must be under 150 characters")] public string Icon { get; set; } } } }
You can add standard MVC data annotations which will be checked on server side validation (when ModelState.IsValid will be fired). Then we should register in Global.asax HTML helper:
/// Global.ascx.cs protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes) jQueryDataAnnotationsProvider.RegisterAdapters(); }
Now we can use it in views to create validation rules for form fields:
<script type="text/javascript" src="/Scripts/jquery.validate.js"></script> <script type="text/javascript"> $().ready(function() { // validate the form on submit $("#formMapMarker").validate(); <%: Html.jQueryValidationFor(model => model.Title) %> <%: Html.jQueryValidationFor(model => model.Date) %> <%: Html.jQueryValidationFor(model => model.Lat) %> <%: Html.jQueryValidationFor(model => model.Lng) %> <%: Html.jQueryValidationFor(model => model.Icon) %> }); </script>
In the result client side validation:
And JavaScript on the page:
<script type="text/javascript"> $().ready(function() { // validate the form when it is submitted $("#formMapMarker").validate(); $("#Title").rules("add", {required: true, maxlength: 250, messages: {required: "Title required",maxlength: "Must be under 250 characters"}}); $("#Date").rules("add", {required: true, date: true, messages: {required: "Date required",date: "Please enter a valid date."}}); $("#Lat").rules("add", {number: true, required: true, messages: {number: "Please enter a valid number.",required: "Latitude required"}}); $("#Lng").rules("add", {number: true, required: true, messages: {number: "Please enter a valid number.",required: "Longitude required"}}); $("#Icon").rules("add", {maxlength: 150, messages: {maxlength: "Must be under 150 characters"}}); }); </script>
P.S.: Good article how to create custom server-side validator and call it within AJAX request: "Combining JQuery Validation with ASP.NET MVC"
Sources: