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.
01 |
public
ActionResult CreateUser()
|
02 |
{
|
03 |
return
View();
|
04 |
}
|
05 |
06 |
[HttpPost]
|
07 |
public
ActionResult
CreateUserPrevious(UserInformation u)
|
08 |
{
|
09 |
return
View("CreateUserInformation", u);
|
10 |
}
|
11 |
12 |
[HttpPost]
|
13 |
public
ActionResult
CreateUserInformation(UserInformation u)
|
14 |
{
|
15 |
if(ModelState.IsValid)
|
16 |
return
View("CreateUserCompanyInformation");
|
17 |
return
View("CreateUserInformation");
|
18 |
}
|
19 |
20 |
[HttpPost]
|
21 |
public
ActionResult
CreateUserCompanyInformation(UserCompanyInformation
uc, UserInformation ui)
|
22 |
{
|
23 |
if
(ModelState.IsValid)
|
24 |
return
View("ThankYou");
|
25 |
return
View("CreateUserCompanyInformation");
|
26 |
}
|
Next create a CreateUser view and add the following lines,
01 |
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
|
02 |
03 |
Inherits="System.Web.Mvc.ViewPage<ClientSideValidationWithDynamicContent.Models.UserInformation>" %>
|
04 |
05 |
<asp:Content
ID="Content1"
ContentPlaceHolderID="TitleContent"
runat="server">
|
06 |
CreateUser
|
07 |
</asp:Content>
|
08 |
09 |
<asp:Content
ID="Content2"
ContentPlaceHolderID="MainContent"
runat="server">
|
10 |
<%
Html.EnableClientValidation();%>
|
11 |
<%using
(Ajax.BeginForm("CreateUserInformation", new
AjaxOptions { OnComplete = "CompleteFunction"
}))
|
12 |
{ %>
|
13 |
<%Html.RenderPartial("CreateUserInformation");
%>
|
14 |
<%} %>
|
15 |
<script
type="text/javascript">
|
16 |
function CompleteFunction(ajaxContext)
{
|
17 |
$("#form0")[0].validationCallbacks =
[];
|
18 |
$clearHandlers($("#form0")[0]);
|
19 |
var newDiv =
document.createElement("div");
|
20 |
$(newDiv).html(ajaxContext.get_data());
|
21 |
var forms =
newDiv.getElementsByTagName("form");
|
22 |
$("#form0").html(forms[0].innerHTML);
|
23 |
$("#form0")[0].action =
forms[0].action;
|
24 |
Sys.Mvc.FormContext._Application_Load();
|
25 |
return false;
|
26 |
}
|
27 |
</script>
|
28 |
</asp:Content>
|
Next create a CreateUserInformation partial view
and add the following lines,
01 |
<%@ Control Language="C#"
|
02 |
03 |
Inherits="System.Web.Mvc.ViewUserControl<ClientSideValidationWithDynamicContent.Models.UserInformation>" %>
|
04 |
05 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
06 |
{
|
07 |
Html.EnableClientValidation();
|
08 |
Html.BeginForm("CreateUserInformation",
"Home");
|
09 |
}%>
|
10 |
<table
id="table1">
|
11 |
<tr
style="background-color:#E8EEF4;font-weight:bold">
|
12 |
<td
colspan="3"
align="center">
|
13 |
User Information
|
14 |
</td>
|
15 |
</tr>
|
16 |
<tr>
|
17 |
<td>
|
18 |
First Name
|
19 |
</td>
|
20 |
<td>
|
21 |
<%=Html.TextBoxFor(a =>
a.FirstName)%>
|
22 |
</td>
|
23 |
<td>
|
24 |
<%=Html.ValidationMessageFor(a =>
a.FirstName)%>
|
25 |
</td>
|
26 |
</tr>
|
27 |
<tr>
|
28 |
<td>
|
29 |
Last Name
|
30 |
</td>
|
31 |
<td>
|
32 |
<%=Html.TextBoxFor(a =>
a.LastName)%>
|
33 |
</td>
|
34 |
<td>
|
35 |
<%=Html.ValidationMessageFor(a =>
a.LastName)%>
|
36 |
</td>
|
37 |
</tr>
|
38 |
<tr>
|
39 |
<td>
|
40 |
Email
|
41 |
</td>
|
42 |
<td>
|
43 |
<%=Html.TextBoxFor(a =>
a.Email)%>
|
44 |
</td>
|
45 |
<td>
|
46 |
<%=Html.ValidationMessageFor(a =>
a.Email)%>
|
47 |
</td>
|
48 |
</tr>
|
49 |
|
50 |
<tr>
|
51 |
<td
colspan="3"
align="center">
|
52 |
<input
type="submit"
name="userInformation"
value="Next"/>
|
53 |
</td>
|
54 |
</tr>
|
55 |
</table>
|
56 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
57 |
Html.EndForm();
|
58 |
%>
|
Next create a CreateUserCompanyInformation partial view and add the following lines,
01 |
<%@ Control Language="C#"
|
02 |
03 |
Inherits="System.Web.Mvc.ViewUserControl<ClientSideValidationWithDynamicContent.Models.UserCompanyInformation>" %>
|
04 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
05 |
{
|
06 |
Html.EnableClientValidation();
|
07 |
Html.BeginForm("CreateUserCompanyInformation","Home");
|
08 |
}%>
|
09 |
<table
id="table1">
|
10 |
<tr
style="background-color:#E8EEF4;font-weight:bold">
|
11 |
<td
colspan="3"
align="center">
|
12 |
User Company Information
|
13 |
</td>
|
14 |
</tr>
|
15 |
<tr>
|
16 |
<td>
|
17 |
Company Name
|
18 |
</td>
|
19 |
<td>
|
20 |
<%=Html.TextBoxFor(a =>
a.CompanyName)%>
|
21 |
</td>
|
22 |
<td>
|
23 |
<%=Html.ValidationMessageFor(a =>
a.CompanyName)%>
|
24 |
</td>
|
25 |
</tr>
|
26 |
<tr>
|
27 |
<td>
|
28 |
Company Address
|
29 |
</td>
|
30 |
<td>
|
31 |
<%=Html.TextBoxFor(a =>
a.CompanyAddress)%>
|
32 |
</td>
|
33 |
<td>
|
34 |
<%=Html.ValidationMessageFor(a =>
a.CompanyAddress)%>
|
35 |
</td>
|
36 |
</tr>
|
37 |
<tr>
|
38 |
<td>
|
39 |
Designation
|
40 |
</td>
|
41 |
<td>
|
42 |
<%=Html.TextBoxFor(a =>
a.Designation)%>
|
43 |
</td>
|
44 |
<td>
|
45 |
<%=Html.ValidationMessageFor(a =>
a.Designation)%>
|
46 |
</td>
|
47 |
</tr>
|
48 |
|
49 |
<tr>
|
50 |
<td
colspan="3"
align="center">
|
51 |
<input
type="button"
name="prevButton"
|
52 |
53 |
onclick="$.post('/Home/CreateUserPrevious',$(this.form).serialize(),function(data){var ajaxcon=new
|
54 |
55 |
Sys.Mvc.AjaxContext();ajaxcon.get_data=function(){return
data};CompleteFunction(ajaxcon);});" id="prevButton"
|
56 |
57 |
value="Previous"/>
|
58 |
<input
type="submit"
name="userCompanyInformation"
value="Next"/>
|
59 |
<%=Html.Hidden("FirstName")%>
|
60 |
<%=Html.Hidden("LastName")%>
|
61 |
<%=Html.Hidden("Email")%>
|
62 |
</td>
|
63 |
</tr>
|
64 |
</table>
|
65 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
66 |
Html.EndForm();
|
67 |
%>
|
Next create a ThankYou partial view and add the
following lines,
01 |
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
|
02 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
03 |
{
|
04 |
Html.EnableClientValidation();
|
05 |
Html.BeginForm();
|
06 |
}%>
|
07 |
Thank you for submitting your
information
|
08 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
09 |
Html.EndForm();
|
10 |
%>
|
Next create a new class file UserInformation.cs inside Model folder and add the following code,
01 |
public
class
UserInformation
|
02 |
{
|
03 |
public
int
Id { get; set; }
|
04 |
05 |
[Required(ErrorMessage = "First Name is required")]
|
06 |
[StringLength(10, ErrorMessage = "First Name max length is 10")]
|
07 |
public
string
FirstName { get; set; }
|
08 |
09 |
[Required(ErrorMessage = "Last Name is required")]
|
10 |
[StringLength(10, ErrorMessage = "Last Name max length is 10")]
|
11 |
public
string
LastName { get; set; }
|
12 |
13 |
[Required(ErrorMessage = "Email is required")]
|
14 |
[RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Email Format is wrong")]
|
15 |
public
string
Email { get; set; }
|
16 |
}
|
Next create a new class file UserCompanyInformation.cs inside Model folder and add the following code,
01 |
public
class
UserCompanyInformation
|
02 |
{
|
03 |
public
int
UserId { get; set; }
|
04 |
05 |
[Required(ErrorMessage = "Company Name is required")]
|
06 |
[StringLength(10, ErrorMessage = "Company Name max length is 10")]
|
07 |
public
string
CompanyName { get; set; }
|
08 |
09 |
[Required(ErrorMessage = "CompanyAddress is required")]
|
10 |
[StringLength(50, ErrorMessage = "Company Address max length is 50")]
|
11 |
public
string
CompanyAddress { get; set; }
|
12 |
13 |
[Required(ErrorMessage = "Designation is required")]
|
14 |
[StringLength(50, ErrorMessage = "Designation max length is 10")]
|
15 |
public
string
Designation { get; set; }
|
16 |
}
|
Next add the necessary script files in Site.Master,
1 |
<script
src="../../Scripts/jquery-1.4.1.js"
type="text/javascript"></script>
|
2 |
<script
src="../../Scripts/MicrosoftAjax.js"
type="text/javascript"></script>
|
3 |
<script
src="../../Scripts/MicrosoftMvcAjax.js"
type="text/javascript"></script>
|
4 |
<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,
01 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
02 |
{
|
03 |
Html.EnableClientValidation();
|
04 |
Html.BeginForm("....","...");
|
05 |
}%>
|
06 |
07 |
08 |
...............................................
|
09 |
...............................................
|
10 |
...............................................
|
11 |
...............................................
|
12 |
13 |
14 |
<%if
(ViewContext.HttpContext.Request.IsAjaxRequest())
|
15 |
Html.EndForm();
|
16 |
%>
|
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.