Ajax Form in ASP.Net MVC

Introduction

It is a practical approach so we will create an example to add a user and show in the list. The add user form will be submitted using JavaScript.

Using the Code

When a form is submitted using a POST request then it returns a response in JSON format. That's why we create a common class so that all form POSTs have a common data structure in response. The following code snippet is for the ResponseData class.

  1. namespace AjaxForm.Serialization  
  2. {  
  3.     public class ResponseData<T>  
  4.     {  
  5.         public T Data { get; set; }  
  6.         public string RedirectUrl { get; set; }  
  7.         public bool IsSuccess { get { return this.Data == null; } }  
  8.     }     
  9. }  
Since we need to return data in JSON format, the action methods will return a JsonResult. We install “Newtonsoft.Json.5.0.8” using the Nuget package and write a custom class that inherits JsonResult. The following is the code snippet for the JsonNetResult class.
  1. using Newtonsoft.Json;  
  2. using Newtonsoft.Json.Serialization;  
  3. using System;  
  4. using System.IO;  
  5. using System.Web;  
  6. using System.Web.Mvc;  
  7.   
  8. namespace AjaxForm.Serialization  
  9. {  
  10.     public class JsonNetResult : JsonResult  
  11.     {  
  12.         public JsonNetResult()  
  13.         {  
  14.             Settings = new JsonSerializerSettings  
  15.             {  
  16.                 ReferenceLoopHandling = ReferenceLoopHandling.Error,  
  17.                 ContractResolver = new CamelCasePropertyNamesContractResolver()  
  18.             };  
  19.         }  
  20.   
  21.         public JsonSerializerSettings Settings { get; private set; }  
  22.   
  23.         public override void ExecuteResult(ControllerContext context)  
  24.         {  
  25.             if (context == null)  
  26.             {  
  27.                 throw new ArgumentNullException("context");  
  28.             }  
  29.             if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))  
  30.             {  
  31.                 throw new InvalidOperationException("JSON GET is not allowed");  
  32.             }  
  33.   
  34.             HttpResponseBase response = context.HttpContext.Response;  
  35.             response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;  
  36.   
  37.             if (this.ContentEncoding != null)  
  38.             {  
  39.                 response.ContentEncoding = this.ContentEncoding;  
  40.             }  
  41.             if (this.Data == null)  
  42.             {  
  43.                 return;  
  44.             }  
  45.             var scriptSerializer = JsonSerializer.Create(this.Settings);  
  46.   
  47.             using (var sw = new StringWriter())  
  48.             {  
  49.                 scriptSerializer.Serialize(sw, this.Data);  
  50.                 response.Write(sw.ToString());  
  51.             }  
  52.         }  
  53.     }  
  54. }  
Now we have done the work for the serialization of the result, thereafter we create a BasController that has methods for the JSON result and model the error as in the following code snippet.
  1. using AjaxForm.Serialization;  
  2. using System.Linq;  
  3. using System.Text;  
  4. using System.Web.Mvc;  
  5.   
  6. namespace AjaxForm.Controllers  
  7. {  
  8.     public class BaseController : Controller  
  9.     {  
  10.         public ActionResult NewtonSoftJsonResult(object data)  
  11.         {  
  12.             return new JsonNetResult  
  13.             {  
  14.                 Data = data,  
  15.                 JsonRequestBehavior = JsonRequestBehavior.AllowGet  
  16.             };  
  17.         }  
  18.   
  19.         public ActionResult CreateModelStateErrors()  
  20.         {  
  21.             StringBuilder errorSummary = new StringBuilder();  
  22.             errorSummary.Append(@"<div class=""validation-summary-errors"" data-valmsg-summary=""true""><ul>");  
  23.             var errors = ModelState.Values.SelectMany(x => x.Errors);  
  24.             foreach(var error in errors)  
  25.             {  
  26.                 errorSummary.Append("<li>" + error.ErrorMessage + "</li>");  
  27.             }  
  28.             errorSummary.Append("</ul></div>");  
  29.             return Content(errorSummary.ToString());  
  30.         }  
  31.     }  
  32. }  
Ajax Form Implementation on UI

To implement the Ajax form we will create a JavaScript namespace in which we define a JavaScript class for the form POST request. The class checks whether the form is valid or not on form submit. If it's valid then it submits, else it will show an error message. You can also define callback methods like onSuccess on initialization of the class. The following is the code snippet for Global namespace:
  1. var Global = {};  
  2. Global.FormHelper = function (formElement, options, onSucccess, onError) {      
  3.     var settings = {};  
  4.     settings = $.extend({}, settings, options);  
  5.   
  6.     formElement.validate(settings.validateSettings);  
  7.     formElement.submit(function (e) {        
  8.         if (formElement.valid()) {  
  9.             $.ajax(formElement.attr("action"), {  
  10.                 type: "POST",  
  11.                 data: formElement.serializeArray(),  
  12.                 success: function (result) {  
  13.                     if (onSucccess === null || onSucccess === undefined) {  
  14.                         if (result.isSuccess) {  
  15.                             window.location.href = result.redirectUrl;  
  16.                         } else {  
  17.                             if (settings.updateTargetId) {  
  18.                                 $("#" + settings.updateTargetId).html(result.data);  
  19.                             }  
  20.                         }  
  21.                     } else {  
  22.                         onSucccess(result);  
  23.                     }  
  24.                 },  
  25.                 error: function (jqXHR, status, error) {  
  26.                     if (onError !== null && onError !== undefined) {  
  27.                         onError(jqXHR, status, error);  
  28.                         $("#" + settings.updateTargetId).html(error);                         
  29.                     }  
  30.                 },  
  31.                 complete: function () {  
  32.                 }  
  33.             });  
  34.         }  
  35.         e.preventDefault();  
  36.     });  
  37.   
  38.     return formElement;  
  39. };  
Now we will create a controller for the UI that handles GET/POST requests for the user add and shows the user list. The following is the code snippet for UserController:
  1. using AjaxForm.Models;  
  2. using AjaxForm.Serialization;  
  3. using System.Collections.Generic;  
  4. using System.Web.Mvc;  
  5.   
  6. namespace AjaxForm.Controllers  
  7. {  
  8.     public class UserController : BaseController  
  9.     {  
  10.         public static List<UserViewModel> users = new List<UserViewModel>();  
  11.   
  12.         public ActionResult Index()  
  13.         {  
  14.             return View(users);  
  15.         }  
  16.   
  17.         [HttpGet]  
  18.         public ActionResult AddUser()  
  19.         {  
  20.             UserViewModel model = new UserViewModel();  
  21.             return View(model);  
  22.         }  
  23.   
  24.         [HttpPost]  
  25.         public ActionResult AddUser(UserViewModel model)  
  26.         {  
  27.             if (ModelState.IsValid)  
  28.             {  
  29.                 users.Add(model);  
  30.                 return NewtonSoftJsonResult(new ResponseData<string> { RedirectUrl = @Url.Action("Index""User") });  
  31.             }  
  32.             return CreateModelStateErrors();  
  33.         }  
  34.     }  
  35. }  
Now we create a view that shows the add user list and renders by Index action. The following is the code snippet for the Index view.
  1. @model List<AjaxForm.Models.UserViewModel>  
  2. <div class="panel panel-primary">  
  3.     <div class="panel-heading panel-head">User List</div>  
  4.     <div class="panel-body">  
  5.         <div class="btn-group">  
  6.             <a id="addUser" href="@Url.Action("AddUser")" class="btn btn-primary">  
  7.                 <i class="fa fa-plus"></i> Add User  
  8.             </a>  
  9.         </div>  
  10.   
  11.         <table class="table table-striped">  
  12.             <thead>  
  13.                 <tr>  
  14.                     <th>UserName</th>  
  15.                     <th>Email</th>  
  16.                 </tr>  
  17.             </thead>  
  18.             <tbody>  
  19.                 @foreach (var item in Model)  
  20.                 {  
  21.                     <tr>  
  22.                         <td>@item.UserName</td>  
  23.                         <td>@item.Email</td>  
  24.                 </tr>  
  25.                 }  
  26.             </tbody>  
  27.         </table>  
  28.     </div>  
  29. </div>  
Then we will create an AddUser view as in the following code snippet:
  1. @model AjaxForm.Models.UserViewModel  
  2.   
  3. <div class="panel panel-primary">  
  4.     <div class="panel-heading panel-head">Add User</div>  
  5.     <div id="frm-add-user" class="panel-body">  
  6.         @using (Html.BeginForm())  
  7.         {  
  8.             <div id="validation-summary"></div>  
  9.             <div class="form-horizontal">  
  10.                 <div class="form-group">  
  11.                     @Html.LabelFor(model => model.UserName, new { @class = "col-lg-2 control-label" })  
  12.                     <div class="col-lg-9">  
  13.                         @Html.TextBoxFor(model => model.UserName, new { @class = "form-control" })   
  14.                         @Html.ValidationMessageFor(model => model.UserName)                        
  15.                     </div>  
  16.                 </div>  
  17.                 <div class="form-group">  
  18.                     @Html.LabelFor(model => model.Email, new { @class = "col-lg-2 control-label" })  
  19.                     <div class="col-lg-9">  
  20.                         @Html.TextBoxFor(model => model.Email, new { @class = "form-control" })  
  21.                         @Html.ValidationMessageFor(model => model.Email)                         
  22.                     </div>  
  23.                 </div>                  
  24.                 <div class="form-group">  
  25.                     <div class="col-lg-9"></div>  
  26.                     <div class="col-lg-3">  
  27.                         <button class="btn btn-success" id="btnSubmit" type="submit">  
  28.                             Submit  
  29.                         </button>  
  30.                     </div>  
  31.                 </div>  
  32.             </div>  
  33.         }  
  34.     </div>  
  35. </div>  
  36.   
  37. @section scripts  
  38. {  
  39.     @Scripts.Render("~/bundles/jqueryval","~/Scripts/global.js","~/Scripts/user_add_user.js")  
  40. }  
Then we will create a JavaScript (user_add_user.js) that initializes the form submit using a POST request. We can pass additional callback methods in it or also pass additional validate settings in this. The following is the code snippet:
  1. (function ($) {  
  2.   
  3.     function AddUser(){  
  4.         var $this = this;  
  5.   
  6.         function initilizeUser() {  
  7.             var formAddUser = new Global.FormHelper($("#frm-add-user form"), { updateTargetId: "validation-summary" })  
  8.         }  
  9.   
  10.         $this.init = function () {  
  11.             initilizeUser();  
  12.         }  
  13.     }  
  14.     $(function () {  
  15.         var self = new AddUser();  
  16.         self.init();  
  17.     })  
  18.   
  19. }(jQuery))  
Now run the application, the landing page shows that it has user the list and adds a user button. Now clicking on the Add User button we have the following Add User screen.

Add User UI Form
                                                         Figure 1: Add User UI Form

Now click on the Submit button and get the result as in the following screen.

Landing Page Screen
                                                            Figure 2: Landing Page Screen

Download

If you would like to download complete solution source code, please click here.
 


Similar Articles