Share via


Form Submit using Ajax in ASP.NET MVC

Introduction

This article introduces a practical approach to how to submit a form using the jQuery Ajax POST request. So, we will create an example to add a user and show in the list. The add user form will be submitted using jQuery Ajax POST request.

Using the Code

There are two thing with respect to one operation in the web. One is sending request to form submit using Ajax POST method on server and another is getting response which is JSON data from server. To keep response data in same structure, we create common class which is ResponseData which code snippet is following.

namespace AjaxForm.Serialization  
{  
    public class  ResponseData<T>  
    {  
        public T Data { get; set; }  
        public string  RedirectUrl { get; set; }  
        public bool  IsSuccess { get  { return  this.Data == null; } }  
    }     
}

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.

using Newtonsoft.Json;  
using Newtonsoft.Json.Serialization;  
using System;  
using System.IO;  
using System.Web;  
using System.Web.Mvc;  
   
namespace AjaxForm.Serialization  
{  
    public class  JsonNetResult : JsonResult  
    {  
        public JsonNetResult()  
        {  
            Settings = new  JsonSerializerSettings  
            {  
                ReferenceLoopHandling = ReferenceLoopHandling.Error,  
                ContractResolver = new  CamelCasePropertyNamesContractResolver()  
            };  
        }  
   
        public JsonSerializerSettings Settings { get; private  set; }  
   
        public override  void ExecuteResult(ControllerContext context)  
        {  
            if (context == null)  
            {  
                throw new  ArgumentNullException("context");  
            }  
            if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))  
            {  
                throw new  InvalidOperationException("JSON GET is not allowed");  
            }  
   
            HttpResponseBase response = context.HttpContext.Response;  
            response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json"  : this.ContentType;  
   
            if (this.ContentEncoding != null)  
            {  
                response.ContentEncoding = this.ContentEncoding;  
            }  
            if (this.Data == null)  
            {  
                return;  
            }  
            var scriptSerializer = JsonSerializer.Create(this.Settings);  
   
            using (var sw = new StringWriter())  
            {  
                scriptSerializer.Serialize(sw, this.Data);  
                response.Write(sw.ToString());  
            }  
        }  
    }  
}

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.

using AjaxForm.Serialization;  
using System.Linq;  
using System.Text;  
using System.Web.Mvc;  
   
namespace AjaxForm.Controllers  
{  
    public class  BaseController : Controller  
    {  
        public ActionResult NewtonSoftJsonResult(object data)  
        {  
            return new  JsonNetResult  
            {  
                Data = data,  
                JsonRequestBehavior = JsonRequestBehavior.AllowGet  
            };  
        }  
   
        public ActionResult CreateModelStateErrors()  
        {  
            StringBuilder errorSummary = new  StringBuilder();  
            errorSummary.Append(@"<div class=""validation-summary-errors"" data-valmsg-summary=""true""><ul>");  
            var errors = ModelState.Values.SelectMany(x => x.Errors);  
            foreach(var error in  errors)  
            {  
                errorSummary.Append("<li>" + error.ErrorMessage + "</li>");  
            }  
            errorSummary.Append("</ul></div>");  
            return Content(errorSummary.ToString());  
        }  
    }  
}

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. We can also define callback methods like onSuccess on initialization of the class. The following is the code snippet for Global namespace.

var Global = {};  
Global.FormHelper = function  (formElement, options, onSucccess, onError) {      
    var settings = {};  
    settings = $.extend({}, settings, options);  
   
    formElement.validate(settings.validateSettings);  
    formElement.submit(function (e) {        
        if (formElement.valid()) {  
            $.ajax(formElement.attr("action"), {  
                type: "POST",   
                data: formElement.serializeArray(),  
                success: function  (result) {  
                    if (onSucccess === null || onSucccess === undefined) {  
                        if (result.isSuccess) {  
                            window.location.href = result.redirectUrl;  
                        } else  {  
                            if (settings.updateTargetId) {  
                                $("#" + settings.updateTargetId).html(result.data);   
                            }  
                        }  
                    } else  {  
                        onSucccess(result);  
                    }  
                },  
                error: function  (jqXHR, status, error) {  
                    if (onError !== null && onError !== undefined) {  
                        onError(jqXHR, status, error);  
                        $("#" + settings.updateTargetId).html(error);                         
                    }  
                },  
                complete: function  () {  
                }  
            });  
        }  
        e.preventDefault();  
    });  
   
    return formElement;  
};

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:

using AjaxForm.Models;  
using AjaxForm.Serialization;  
using System.Collections.Generic;  
using System.Web.Mvc;  
   
namespace AjaxForm.Controllers  
{  
    public class  UserController : BaseController  
    {  
        public static  List<UserViewModel> users = new List<UserViewModel>();  
   
        public ActionResult Index()  
        {  
            return View(users);  
        }  
   
        [HttpGet]  
        public ActionResult AddUser()  
        {  
            UserViewModel model = new  UserViewModel();  
            return View(model);  
        }  
   
        [HttpPost]  
        public ActionResult AddUser(UserViewModel model)  
        {  
            if (ModelState.IsValid)  
            {  
                users.Add(model);  
                return NewtonSoftJsonResult(new ResponseData<string> { RedirectUrl = @Url.Action("Index", "User") });   
            }  
            return CreateModelStateErrors();  
        }  
    }  
}

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.

@model List<AjaxForm.Models.UserViewModel>  
<div class="panel panel-primary">  
    <div class="panel-heading panel-head">User List</div>  
    <div class="panel-body">  
        <div class="btn-group">  
            <a id="addUser" href="@Url.Action("AddUser")" class="btn btn-primary">  
                <i class="fa fa-plus"></i> Add User  
            </a>  
        </div>  
   
        <table class="table table-striped">  
            <thead>  
                <tr>  
                    <th>UserName</th>  
                    <th>Email</th>  
                </tr>  
            </thead>  
            <tbody>  
                @foreach (var item in Model)  
                {  
                    <tr>  
                        <td>@item.UserName</td>  
                        <td>@item.Email</td>  
                </tr>  
                }  
            </tbody>  
        </table>  
    </div>  
</div>

Then we will create an AddUser view as in the following code snippet:

@model AjaxForm.Models.UserViewModel  
   
<div class="panel panel-primary">  
    <div class="panel-heading panel-head">Add User</div>  
    <div id="frm-add-user" class="panel-body">  
        @using (Html.BeginForm())  
        {  
            <div id="validation-summary"></div>  
            <div class="form-horizontal">  
                <div class="form-group">  
                    @Html.LabelFor(model => model.UserName, new { @class = "col-lg-2 control-label" })  
                    <div class="col-lg-9">  
                        @Html.TextBoxFor(model => model.UserName, new { @class = "form-control" })   
                        @Html.ValidationMessageFor(model => model.UserName)                        
                    </div>  
                </div>  
                <div class="form-group">  
                    @Html.LabelFor(model => model.Email, new { @class = "col-lg-2 control-label" })  
                    <div class="col-lg-9">  
                        @Html.TextBoxFor(model => model.Email, new { @class = "form-control" })  
                        @Html.ValidationMessageFor(model => model.Email)                         
                    </div>  
                </div>                  
                <div class="form-group">  
                    <div class="col-lg-9"></div>  
                    <div class="col-lg-3">  
                        <button class="btn btn-success" id="btnSubmit" type="submit">  
                            Submit  
                        </button>  
                    </div>  
                </div>  
            </div>  
        }  
    </div>  
</div>  
   
@section scripts  
{  
    @Scripts.Render("~/bundles/jqueryval","~/Scripts/global.js","~/Scripts/user_add_user.js")  
}

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:

(function ($) {  
   
    function AddUser(){  
        var $this = this;  
   
        function initilizeUser() {  
            var formAddUser = new Global.FormHelper($("#frm-add-user form"), { updateTargetId: "validation-summary"  })  
        }  
   
        $this.init = function  () {  
            initilizeUser();  
        }  
    }  
    $(function () {  
        var self = new AddUser();  
        self.init();  
    })  
   
}(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.

Figure 1: Add User UI Form

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

Figure 2: Landing Page Screen

Download

You can download complete solution from MSDN Developer Code Sample. Please follow following link to download it.

https://code.msdn.microsoft.com/Ajax-Form-in-ASPNet-MVC-fddd0818

See Also

There are more articles available which are related to ASP.NET MVC. Please go through following links.

  1. Live Environment For ASP.NET MVC Application in Development
  2. Html.Action And Html.RenderAction In ASP.NET MVC