ASP.NET MVC Client Side Validation With Ajax.BeginForm
Introduction:
The ASP.NET MVC Ajax.BeginForm HTML helper make it very easy to submit form asynchronously and allows to perform partial page updates. That's why lot of developers likes to use Ajax.BeginForm HTML helper. In my last blog post I talked about how you can implement client-side validation for dynamic contents at here. I showed you that how you can leverage jQuery to make it possible. This will work very well if you want to use only jQuery. But what if you want to use Ajax.BeginForm Helper? So in this article I will show you how you can implement client-side validation for dynamic contents using Ajax.BeginForm.
Description:
Here I will continue to use the last example which was presented at here with some changes. First of all add the following code in HomeController.cs.
public ActionResult CreateUser() { return View(); } [HttpPost] public ActionResult CreateUserPrevious(UserInformation u) { return View("CreateUserInformation", u); } [HttpPost] public ActionResult CreateUserInformation(UserInformation u) { if(ModelState.IsValid) return View("CreateUserCompanyInformation"); return View("CreateUserInformation"); } [HttpPost] public ActionResult CreateUserCompanyInformation(UserCompanyInformation uc, UserInformation ui) { if (ModelState.IsValid) return View("ThankYou"); return View("CreateUserCompanyInformation"); }
Next create a CreateUser view and add the following lines,
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ClientSideValidationWithDynamicContent.Models.UserInformation>" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> CreateUser </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <% Html.EnableClientValidation();%> <%using (Ajax.BeginForm("CreateUserInformation", new AjaxOptions { OnComplete = "CompleteFunction" })) { %> <%Html.RenderPartial("CreateUserInformation"); %> <%} %> <script type="text/javascript"> function CompleteFunction(ajaxContext) { $("#form0")[0].validationCallbacks = []; $clearHandlers($("#form0")[0]); var newDiv = document.createElement("div"); $(newDiv).html(ajaxContext.get_data()); var forms = newDiv.getElementsByTagName("form"); $("#form0").html(forms[0].innerHTML); $("#form0")[0].action = forms[0].action; Sys.Mvc.FormContext._Application_Load(); return false; } </script> </asp:Content>
Next create a CreateUserInformation partial view and add the following lines,
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ClientSideValidationWithDynamicContent.Models.UserInformation>" %> <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) { Html.EnableClientValidation(); Html.BeginForm("CreateUserInformation", "Home"); }%> <table id="table1"> <tr style="background-color:#E8EEF4;font-weight:bold"> <td colspan="3" align="center"> User Information </td> </tr> <tr> <td> First Name </td> <td> <%=Html.TextBoxFor(a => a.FirstName)%> </td> <td> <%=Html.ValidationMessageFor(a => a.FirstName)%> </td> </tr> <tr> <td> Last Name </td> <td> <%=Html.TextBoxFor(a => a.LastName)%> </td> <td> <%=Html.ValidationMessageFor(a => a.LastName)%> </td> </tr> <tr> <td> Email </td> <td> <%=Html.TextBoxFor(a => a.Email)%> </td> <td> <%=Html.ValidationMessageFor(a => a.Email)%> </td> </tr> <tr> <td colspan="3" align="center"> <input type="submit" name="userInformation" value="Next"/> </td> </tr> </table> <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) Html.EndForm(); %>
Next create a CreateUserCompanyInformation partial view and add the following lines,
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ClientSideValidationWithDynamicContent.Models.UserCompanyInformation>" %> <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) { Html.EnableClientValidation(); Html.BeginForm("CreateUserCompanyInformation","Home"); }%> <table id="table1"> <tr style="background-color:#E8EEF4;font-weight:bold"> <td colspan="3" align="center"> User Company Information </td> </tr> <tr> <td> Company Name </td> <td> <%=Html.TextBoxFor(a => a.CompanyName)%> </td> <td> <%=Html.ValidationMessageFor(a => a.CompanyName)%> </td> </tr> <tr> <td> Company Address </td> <td> <%=Html.TextBoxFor(a => a.CompanyAddress)%> </td> <td> <%=Html.ValidationMessageFor(a => a.CompanyAddress)%> </td> </tr> <tr> <td> Designation </td> <td> <%=Html.TextBoxFor(a => a.Designation)%> </td> <td> <%=Html.ValidationMessageFor(a => a.Designation)%> </td> </tr> <tr> <td colspan="3" align="center"> <input type="button" name="prevButton" onclick="$.post('/Home/CreateUserPrevious',$(this.form).serialize(),function(data){var ajaxcon=new Sys.Mvc.AjaxContext();ajaxcon.get_data=function(){return data};CompleteFunction(ajaxcon);});" id="prevButton" value="Previous"/> <input type="submit" name="userCompanyInformation" value="Next"/> <%=Html.Hidden("FirstName")%> <%=Html.Hidden("LastName")%> <%=Html.Hidden("Email")%> </td> </tr> </table> <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) Html.EndForm(); %>
Next create a ThankYou partial view and add the following lines,
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %> <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) { Html.EnableClientValidation(); Html.BeginForm(); }%> Thank you for submitting your information <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) Html.EndForm(); %>
Next create a new class file UserInformation.cs inside Model folder and add the following code,
public class UserInformation { public int Id { get; set; } [Required(ErrorMessage = "First Name is required")] [StringLength(10, ErrorMessage = "First Name max length is 10")] public string FirstName { get; set; } [Required(ErrorMessage = "Last Name is required")] [StringLength(10, ErrorMessage = "Last Name max length is 10")] public string LastName { get; set; } [Required(ErrorMessage = "Email is required")] [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Email Format is wrong")] public string Email { get; set; } }
Next create a new class file UserCompanyInformation.cs inside Model folder and add the following code,
public class UserCompanyInformation { public int UserId { get; set; } [Required(ErrorMessage = "Company Name is required")] [StringLength(10, ErrorMessage = "Company Name max length is 10")] public string CompanyName { get; set; } [Required(ErrorMessage = "CompanyAddress is required")] [StringLength(50, ErrorMessage = "Company Address max length is 50")] public string CompanyAddress { get; set; } [Required(ErrorMessage = "Designation is required")] [StringLength(50, ErrorMessage = "Designation max length is 10")] public string Designation { get; set; } }
Next add the necessary script files in Site.Master,
<script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script> <script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> <script src="../../Scripts/MicrosoftMvcValidation.debug.js" type="text/javascript"></script>
Now let's see what the above code is doing? First of all, note that here i am using the same model classes with same validation rules used in last article. All the controller actions code is also same except one step(which returns View("ThankYou") instead of Content).
The big idea is to note here is that every partial view contains the following extra lines,
<%if (ViewContext.HttpContext.Request.IsAjaxRequest()) { Html.EnableClientValidation(); Html.BeginForm("....","..."); }%> ............................................... ............................................... ............................................... ............................................... <%if (ViewContext.HttpContext.Request.IsAjaxRequest()) Html.EndForm(); %>
These lines of code(Html.BeginForm method) are necessary to let the ASP.NET MVC to emit the validation scripts during partial post back. Inside Html.BeginForm method, action and controller parameters are also set so that next time Ajax.BeginForm will post the form to this new action.
Inside CreateUser view, I am handling OnComplete event of Ajax.BeginForm method. Inside this event, previous handlers and callbacks are cleared so that no memory leakage happens. Then just replace the current page form contents with the new form contents which was received by submitting the asynchronous form. Here the current form action is also replaced with new form action so that Ajax.BeginForm will post the form to new action. Finally just call Sys.Mvc.FormContext._Application_Load method so that ASP.NET MVC initialize the new validation rules.
Another interesting point worth to discuss here is that Previous button uses jQuery.post method to send a request to an action and then this action response is used to create AjaxContext object and pass this AjaxContext object to OnComplete event function. This allows you to bypass the client side validation.
Summary:
In this article, I discuss how to enable client side validation for dynamic contents which you get from using Ajax.BeginForm. The example in this article will helps you to enable the client side validation for dynamic contents with Ajax.BeginForm very easily. Just download the sample application and run the application and check it out. I hope you will enjoy this article too.