AJAX is often used to post data from the client side to the server side asynchronously without refreshing the whole page. As I recently discovered, the data that needs to be posted can be in various types and sometimes quite complex. In this article, I will share with you how to post data of different types including integers, strings, objects, and collections from view to controller using AJAX in ASP.NET Core MVC web application.
Setting up the project
Create a new ASP.NET Core MVC web application and name it AjaxDotNetCoreExample. Please refer to this Microsoft Learn page for information on how to create an ASP.NET Core MVC web app in Visual Studio. Next, in Models folder, create a new class Person
with Id, Name, and Age properties.
Person.cs:
public class Person
{
public int Id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
}
Then, in the same Models folder, create a new class JsonResponseViewModel
that will be the response returned from controller to view. Make sure to add a Serializable
attribute to the class so that it can be easily serialized to a JSON string.
JsonResponseViewModel.cs:
[Serializable]
public class JsonResponseViewModel
{
public int ResponseCode { get; set; }
public string ResponseMessage { get; set; }
}
Posting integers and strings with AJAX
First, let’s post an integer and a string from view to controller using AJAX. We will start with controller then move on to views. In Controllers folder find HomeController.cs, add a HttpPost
method AjaxPostSimpleDataType
to HomeController
class. This method is where the AJAX will post data to. It basically constructs a Person object from the name and age parameter, serialize the object to a JSON string that’s part of the the response message, and return a JsonResponseViewModel
to the view.
HomeController.cs:
using AjaxDotNetCoreExample.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace AjaxDotNetCoreExample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult AjaxPostSimpleDataType(string name, int age)
{
var person = new Person() { Name = name, Age = age };
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostSimpleDataType()</strong>: " +
JsonConvert.SerializeObject(person)
};
return Json(jsonResponseVm);
}
public IActionResult Privacy()
{
return View();
}
}
}
Next, in Views -> Home folder find Index.cshtml, add a simple form that consists of the name and age input. Also, above the form, add a div
message placeholder.
Index.cshtml:
<div class="col-6">
<h5>Example of using AJAX to post various data types in .NET Core</h5>
<div class="text-danger my-4" id="msg"></div>
<div class="form-group">
<label for="inputName">Name</label>
<input class="form-control" id="inputName" placeholder="Enter name">
</div>
<div class="form-group mt-2">
<label for="inputAge">Age</label>
<input class="form-control" id="inputAge" placeholder="Enter age">
</div>
<button class="btn btn-outline-primary mt-4" id="btnPostSimpleDataType">
Post Simple Data Types
</button>
</div>
Then, let’s add some JavaScript code that handles button click and the AJAX call to the site.js file in wwwroot -> js folder. This function first gets the value of name and age input from the view, invoke the AJAX call to post these values to AjaxPostSimpleDataType
method in HomeController
. Upon success, a message sent from the controller will be displayed at the placeholder above the form. It’s very important that the name of the data fields match the name of parameters for the method. For example, name and age are fields of data in AJAX call as well as parameters in the AjaxPostSimpleDataType
method. Also, notice the contentType
is a bit uncommon.
site.js:
$(function () {
$('#btnPostSimpleDataType').on('click', function () {
var data = { name: $('#inputName').val(), age: $('#inputAge').val() };
$.ajax({
type: 'post',
url: '/Home/AjaxPostSimpleDataType',
contentType: 'application/x-www-form-urlencoded',
data: data,
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
});
Of course, the above code can also be placed inside the view, instead of a separate js file. In that case, the url
can be replaced with '@Url.Action("AjaxPostSimpleDataType", "Home")'
which is actually more preferable than a hard-coded url
.
Posting an object with AJAX
Now let’s post an object from view to controller using AJAX. Again, we will start with controller then move on to views. In Controllers folder find HomeController.cs file, add a HttpPost
method AjaxPostObject
to the existing code. This method takes a Person object from the parameter and serializes it to a JSON string that’s part of a response message. Notice a [FromBody]
attribute is added to the parameter. This is different from the case when posting simple data types like integers or strings.
HomeController.cs:
using AjaxDotNetCoreExample.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace AjaxDotNetCoreExample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult AjaxPostSimpleDataType(string name, int age)
{
var person = new Person() { Name = name, Age = age };
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostSimpleDataType()</strong>: " +
JsonConvert.SerializeObject(person)
};
return Json(jsonResponseVm);
}
[HttpPost]
public JsonResult AjaxPostObject([FromBody] Person person)
{
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostObject():</strong>: " +
JsonConvert.SerializeObject(person)
};
return Json(jsonResponseVm);
}
public IActionResult Privacy()
{
return View();
}
}
}
For the view we can use the existing form, just need to add a button with different id to Index.cshtml file in Views -> Home folder.
Index.cshtml:
<div class="col-6">
<h5>Example of using AJAX to post various data types in .NET Core</h5>
<div class="text-danger my-4" id="msg"></div>
<div class="form-group">
<label for="inputName">Name</label>
<input class="form-control" id="inputName" placeholder="Enter name">
</div>
<div class="form-group mt-2">
<label for="inputAge">Age</label>
<input class="form-control" id="inputAge" placeholder="Enter age">
</div>
<button class="btn btn-outline-primary mt-4" id="btnPostSimpleDataType">
Post Simple Data Types
</button>
<button class="btn btn-outline-primary mt-4" id="btnPostObject">
Post an Object
</button>
</div>
Next, add some JavaScript code that handles button click and AJAX call to the existing site.js file in wwwroot -> js folder. Compared with posting simple data types, we can see that the AJAX for posting an object has a different contentType
, and the data is wrapped in JSON.stringify()
. Also, a dataType
field with the value json is added.
site.js:
$(function () {
$('#btnPostSimpleDataType').on('click', function () {
var data = { name: $('#inputName').val(), age: $('#inputAge').val() };
$.ajax({
type: 'post',
url: '/Home/AjaxPostSimpleDataType',
contentType: 'application/x-www-form-urlencoded',
data: data,
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
$('#btnPostObject').on('click', function () {
var data = { name: $('#inputName').val(), age: $('#inputAge').val() };
$.ajax({
type: 'post',
url: '/Home/AjaxPostObject',
contentType: 'application/json; charset=urf-8',
data: JSON.stringify(data),
dataType: "json",
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
});
Posting a collection with AJAX
The last part consists of posting a collection of objects from view to controller using AJAX. As always, starting with the controller, add a HttpPost
method AjaxPostCollection
to HomeController.cs file in Controllers folder. Notice the method’s parameter is an IEnumerable<Person>
type and contains a [FromBody]
attribute. Then, modify the Index
method to generate a list of Person
object and return to the view.
HomeController.cs:
using AjaxDotNetCoreExample.Models;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace AjaxDotNetCoreExample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
var people = new List<Person>
{
new Person() { Id = 1, Name = "Alex", Age = 30 },
new Person() { Id = 2, Name = "John", Age = 40 },
new Person() { Id = 3, Name = "Luke", Age = 50 },
};
return View(people);
}
[HttpPost]
public JsonResult AjaxPostSimpleDataType(string name, int age)
{
var person = new Person() { Name = name, Age = age };
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostSimpleDataType()</strong>: " +
JsonConvert.SerializeObject(person)
};
return Json(jsonResponseVm);
}
[HttpPost]
public JsonResult AjaxPostObject([FromBody] Person person)
{
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostObject():</strong>: " +
JsonConvert.SerializeObject(person)
};
return Json(jsonResponseVm);
}
[HttpPost]
public JsonResult AjaxPostCollection([FromBody] IEnumerable<Person> people)
{
var jsonResponseVm = new JsonResponseViewModel()
{
ResponseCode = 0,
ResponseMessage =
"Meesage from <strong>AjaxPostCollection()</strong>: " +
JsonConvert.SerializeObject(people)
};
return Json(jsonResponseVm);
}
public IActionResult Privacy()
{
return View();
}
}
}
Next, in Views -> Home folder find Index.cshtml, set the model of the view to be IEnumerable<Person>
, then add a Boostrap’s list group displaying each person’s name and age, separated by a space. Each list group item has the value of the binding person’s Id.
Index.cshtml:
@model IEnumerable<Person>
<div class="col-6">
<h5>Example of using AJAX to post various data types in .NET Core</h5>
<div class="text-danger my-4" id="msg"></div>
<div class="form-group">
<label for="inputName">Name</label>
<input class="form-control" id="inputName" placeholder="Enter name">
</div>
<div class="form-group mt-2">
<label for="inputAge">Age</label>
<input class="form-control" id="inputAge" placeholder="Enter age">
</div>
<button class="btn btn-outline-primary mt-4" id="btnPostSimpleDataType">
Post Simple Data Types
</button>
<button class="btn btn-outline-primary mt-4" id="btnPostObject">
Post an Object
</button>
<hr class="my-4" />
<ul class="list-group">
@foreach(var p in Model)
{
<li class="list-group-item" [email protected]>
<div>@p.Name @p.Age</div>
</li>
}
</ul>
<button class="btn btn-outline-primary mt-4" id="btnPostCollection">
Post a Collection
</button>
</div>
Last, in wwwroot -> js folder, add some JavaScript code to the existing site.js file to handle button click and AJAx call. It gets necessary values from the list group, constructs an array of Person
object, then post the array to controller through AJAX call.
$(function () {
$('#btnPostSimpleDataType').on('click', function () {
var data = { name: $('#inputName').val(), age: $('#inputAge').val() };
$.ajax({
type: 'post',
url: '/Home/AjaxPostSimpleDataType',
contentType: 'application/x-www-form-urlencoded',
data: data,
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
$('#btnPostObject').on('click', function () {
var data = { name: $('#inputName').val(), age: $('#inputAge').val() };
$.ajax({
type: 'post',
url: '/Home/AjaxPostObject',
contentType: 'application/json; charset=urf-8',
data: JSON.stringify(data),
dataType: "json",
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
$('#btnPostCollection').on('click', function () {
var arr = [];
$('.list-group li').each(function () {
var person = {};
person.Id = $(this).val();
person.Name = $(this).find('div').text().split(" ")[0];
person.Age = $(this).find('div').text().split(" ")[1];
arr.push(person);
})
$.ajax({
type: 'post',
url: '/Home/AjaxPostCollection',
contentType: 'application/json; charset=urf-8',
data: JSON.stringify(arr),
dataType: "json",
success: function (res) {
if (res.responseCode == 0) {
$('#msg').html(res.responseMessage);
}
},
error: function (xhr, status, error) { alert("error"); }
});
});
});
The takeaway
Now we know how to post simple data types, an object, or a collection from view to controller using AJAX. It should be able to cover most of what’s needed in daily basis. Please feel free to get the complete code from this GitHub repo and leave comments below if you have any additional thoughts. Good luck!