Sunteți pe pagina 1din 20

Implementing AJAX in ASP.

NET MVC

Azim Zahir, 14 Mar 2015


4.90 (17 votes)

Rate: vote 1vote 2vote 3vote 4vote 5


This tip explains implementing AJAX in ASP.NET MVC.
Download source - 52.6 KB

Introduction
This tip explains how we can implement AJAX in ASP.NET MVC. Here, I have attempted to explain the
concept of partial page updates using a partial view to display product details asynchronously. For
simplicity, I have stored details of three products statically in a list. The application searches the
product code entered by a user and displays the corresponding product details.

Background
Traditional web applications rely on synchronous method calls to process data. The entire web page
is posted to the server each time data is submitted through the page, causing performance delays.

This problem can be overcome by using AJAX. AJAX allows web applications to call methods
asynchronously. Instead of posting the entire page to the web server, only the required data is
posted. This improves the overall performance of the web applications.

Using the Code


Begin by creating a new ASP.NET MVC4 project as follows:

We will use a model class to display data in a partial view. For this, we have to add a Product class
in the Models folder as follows by right clicking on the Models folder and selecting the Add Class
option:
Following is the code of the Product class:

Hide Copy Code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AJAXDemo.Models
{
public class Product
{
public string ProdCode
{
get;
set;
}
public string ProdName
{
get;
set;
}
public int ProdQty
{
get;
set;
}
}
}
Then, add new layout in the Shared folder under the Views folder as follows:

Following is the code of the _Layout.cshtml file:

Hide Copy Code


@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Layout</title>
@RenderSection("scripts")
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>

This layout will be used by the Index view. In this layout, the RenderSection() method defines a
placeholder for the scripts section and the RenderBody() method defines a placeholder for the
main content of the Index view.

Add a new controller as follows by right clicking on the Controllers folder:

Following is the code of the Index() method:

Hide Copy Code


public ActionResult Index()
{
Product p1 = new Product { ProdCode = "P001", ProdName = "Mobile", ProdQty = 75 };
Product p2 = new Product { ProdCode = "P002", ProdName = "Laptop", ProdQty = 125 };
Product p3 = new Product { ProdCode = "P003", ProdName = "Netbook", ProdQty = 100 };
prodList.Add(p1);
prodList.Add(p2);
prodList.Add(p3);
return View();
}

This code creates three product objects and adds them to a static list called prodList which is
declared at the class level and it renders the view associated with the Index view.
Add the view corresponding to the above action method as follows by right clicking on
the Index() method in the controller:
(Note: Remember to select the layout page while adding the Index view.)

Following is the code of the Index.cshtml view:

Hide Copy Code


@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@section scripts
{
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
}

<h2>Index</h2>
@Ajax.BeginForm("ShowDetails","Ajax",
new AjaxOptions
{ HttpMethod = "POST", UpdateTargetId = "div1",
InsertionMode = InsertionMode.Replace, LoadingElementId = "waitimage" })
<h1>Enter Product Code</h1>
<h2>
Product Code: @Html.TextBox("txtCode")<br />
<input type="submit" value="Show Details" />
<input type="reset" value="Clear"/>
</h2>
@{Html.EndForm();}
<br />
<img id="waitimage" src="~/Images/loading42.gif" style="display:none" />
<br />
<div id="div1">
</div>

The above view references the jquery.unobtrusive-ajax.js script to implement the AJAX functionality. It
also uses a div with the id "div1" to display the requested product details. It uses
the Ajax.BeginForm() helper method to accept product code and submit it asynchronously. The
first parameter of the Ajax.BeginForm() method specifies the name of the action method to be
invoked to process the input data, the second parameter specifies the name of the controller and the
third parameter specifies the AjaxOptions to be used. In the AjaxOptions,
the HttpMethod property specifies the HTTP method to be used, the UpdateTargetId property
specifies the ID of the div element where the partial view will be displayed,
the InsertionMode property specifies the mode of insertion of the partial view, and
the LoadingElemetId property specifies the ID of the image to be displayed while waiting for the
asynchronous call to be completed and the view to be rendered.

The InsertionMode property can have one of the following values:

InsertionMode.InsertAfter - The new details are added after the existing details
InsertionMode.InsertBefore - The new details are added before the existing details
InsertionMode.Replace - The new details replace the existing details

In order to process the input and search the product code entered by the user, we add a method in
the controller which returns a partial view as follows:

Hide Copy Code


public PartialViewResult ShowDetails()
{
System.Threading.Thread.Sleep(3000);
string code = Request.Form["txtCode"];
Product prod = new Product();
foreach(Product p in prodList)
{
if (p.ProdCode == code)
{
prod = p;
break;
}
}
return PartialView("_ShowDetails", prod);
}
The above code searches the entered product code and returns the product corresponding to it
using a partial view. It uses the Thread.Sleep() method to simulate delay in fetching the product
details. This allows you to view the page loading animation while waiting for the asynchronous
method call to complete.

In order to display the product details, we have to add a strongly typed partial view as follows by
right clicking on the method and selecting the Add View option:

Following is the code of the _ShowDetails view:

Hide Copy Code


@model AJAXDemo.Models.Product

@if(Model.ProdCode==null)
{
<h1>Invalid Product Code</h1>
}
else
{
<h1>Product Details</h1>
<h2>
Product Code: @Model.ProdCode<br />
Product Name: @Model.ProdName<br />
Product Quantity: @Model.ProdQty<br />
</h2>
}

The above code displays the product details if the product code is found and the message "Invalid
Product Code" if it is not found.

Before executing the application, we have to specify the routing information in the RouteConfig.cs file
in the App_Start folder as follows:

Hide Copy Code


routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Ajax", action = "Index", id =
UrlParameter.Optional }
);

Also, we need to enable unobtrusive JavaScript by adding the "UnobtrusiveJavaScriptEnabled"


key under the <configuration> element in the Web.config file as follows:

Hide Copy Code


<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

On execution, the application produces the following output:


Entering a product code and clicking the submit button displays the corresponding product details
asynchronously.

Points of Interest
AJAX is a very important feature of web applications and it provides significant performance
advantage over traditional web applications.

I have developed the application using Microsoft Visual Studio Express 2013 for Web.

License
This article, along with any associated source code and files, is licensed under The Code Project Open
License (CPOL)

Share
About the Author

Azim Zahir
Instructor / Trainer NIIT, India

India

I am a trainer by profession. Currently I am working with NIIT (Mumbai, India)as a Senior Faculty. I
enjoy programming as a hobby. My favorite technologies are Flash, Flex and Silverlight.

Of late I have developed keen interest in WPF and Windows Mobile programming.

Apart from computers, my favorite pastime is bicycling.

Do GET, POST, PUT, DELETE in asp.net MVC with


Jquery ajax
DiponRoy, 25 Jul 2014
4.70 (32 votes)

Rate: vote 1vote 2vote 3vote 4vote 5


Download RequestsInMvc.zip - 4.2 MB

Introduction
In asp.net MVC we have seen http verbs like HttpGet, HttpPost, HttpPut and HttpDelete. Here will
see how can we use these words in actions, what does these words mean, and how can use jquery
ajax calls for such http verb enable actions.

Why use HttpVerbs?


Let's examine these actions

UrlRespone()
1. Is accessible using browser url
2. It can also be used for Ajax calls

Hide Copy Code


public JsonResult UrlResponse() //accessible using Url
{
return Json(new { Name = "UrlResponse", Response = "Response from Get", Date =
DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") }, JsonRequestBehavior.AllowGet);
}

TypedResponse()
1. It can only be usable using Ajax calls using (type: "GET")
2. If try to access using browser url, it would throw error

Hide Copy Code


[HttpGet]
public JsonResult TypedResponse() //error if try to access using Url
{
return Json(new { Name = "TypedResponse", Response = "Response from Get", Date =
DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") }, JsonRequestBehavior.AllowGet);
}

MultipleTypedResponse()
1. If try to access using browser url, it would throw error
2. It can only be usable using Ajax calls using (type: "GET"/"POST")

Hide Copy Code


[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
//or [AcceptVerbs("GET","POST")]
public JsonResult MultipleTypedResponse()
{
return Json(new { Name = "MultipleTypedResponse", Response = "Response from Get", Date =
DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") }, JsonRequestBehavior.AllowGet);
}

Now lets see how can use http verbed actions in MVC, and Jquery Ajax calls using $.ajax objects
together. But there are some concern with

1. How to specify a particular action for Ajax call.


- At url attribute use specify the controller and actions as /{controller}/{action} pattern;

url: '/User/Create',
url: '/User/Get/20',

2. How to specify the http verb in Ajax call


- At the type attribute with values GET/ POST/ PUT/ DELETE of the Ajax object

type: "POST",
type: "GET",

3. How to pass parameters to that action if needed.


- At data attribute we specify the data to be passed to a particular action.

Hide Copy Code


data: JSON.stringify({ user: { name: 'Rintu', email: 'Rintu@gmial.com' } }),
Hide Copy Code
data: { name: 'Rintu', email: 'Rintu@gmial.com' },

- For GET requests we can also specify the datas at the url attribute, but we need to work with
route configurations too. (Here we are avoiding things, concerning rout config).

url: '/User/Get/20',
4. Where to find the response data.
- At the success attribute we will get the response datas.

success: function (data) {


alert(data);
},

5. Is there any error


- At the error attribute we will get error detail, if any found at the server end

Hide Copy Code


error: function (xhr) {
alert('error');
}

HttpGet
MVC action

Hide Copy Code


// GET: /User/Get/5
[HttpGet]
public JsonResult Get(int id)
{
return Json("Response from Get", JsonRequestBehavior.AllowGet);
}

ajax call
1. passing value of id as url: '/User/Get/20'
2. no use of data attr at the ajax object.

Hide Copy Code


/*GET*/
$.ajax({
url: '/User/Get/20',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});
HttpPost
MVC action

Hide Copy Code


// POST: /User/Create
[HttpPost]
public JsonResult Create(User user)
{
return Json("Response from Create");
}

ajax call
Data is passed to action using the data attribute of the ajax object

Hide Copy Code


/*POST*/
$.ajax({
url: '/User/Create',
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ user: { name: 'Rintu', email: 'Rintu@gmial.com' } }),
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
})

HttpPut
MVC action

Hide Copy Code


// PUT: /User/Edit
[HttpPut]
public JsonResult Edit(int id, User user)
{
return Json("Response from Edit");
}

ajax call

Hide Copy Code


/*PUT*/
$.ajax({
url: '/User/Edit',
dataType: "json",
type: "PUT",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ id: 100, user: {name: 'Rintu', email: 'Rintu@gmial.com'} }),
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});

HttpDelete
MVC action

Hide Copy Code


// DELETE: /User/Delete
[HttpDelete]
public JsonResult Delete(int id)
{
return Json("Response from Delete");
}

ajax call

Hide Copy Code


/*DELETE*/
$.ajax({
url: '/User/Delete',
dataType: "json",
type: "DELETE",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({id: 20}),
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});

Well they all worked fine, but there are some interesting things too. Lets just talk about them too.
Lets take some closer looks for GET's
when we are working with httpGet verbed actions we may face conserens like,

Pass data as objects rather than


JSON.stringify(object)
action

Hide Copy Code


// GET: /User/Contains
[HttpGet] //use or not works same
public JsonResult Contains(string name, string email)
{
return Json("Response from Contains", JsonRequestBehavior.AllowGet);
}

ajax call

Hide Copy Code


/*GET*/
$.ajax({
url: '/User/Contains',
dataType: "json",
type: "GET",
contentType: 'application/x-www-form-urlencoded; charset=utf-8', //replace /json to the
urlenoded
data: { name: 'Rintu', email: 'Rintu@gmial.com' }, // data is not json
async: true,
processData: true, //important to use it
as true
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});

Lets find some difference with the previous HttpGet verb use.

At the old one, we have used,


1. url: '/User/Get/20'
2. There was no data attribute at the Ajax object.
At this one we have used,
1. url: '/User/Create'
2. data: { name: 'Rintu', email: 'Rintu@gmial.com' }
And this would work just fine.

What if we try to pass values using both url and


data?
action

Hide Copy Code


// GET: /User/Find/1/30 or
// GET: /User/Find
[HttpGet]
public JsonResult Find(int pageNo, int pageSize, User user)
{
return Json("Response from Find", JsonRequestBehavior.AllowGet);
}

ajax call,

Hide Copy Code


/*GET*/
$.ajax({
url: '/User/Find/3/5',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
//pageNo: 2, pageSize: 20 would not be posted to the action,
//it would be 3 and 5 as we specified it at ajax url
//and user would be null
data: { pageNo: 2, pageSize: 60, user: { name: 'Rintu', email: 'Rintu@gmial.com' } },
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
})

At action pageNo and pageSize would be 1 and 30 rather than 2 and 20, as priority of the url data
pass is higher.

This type of "GET" requests with data in url, helps in action overloading too. In such case, we have to
be aware with the route configurations.
Yes there is another problem with the user object here, and we are going to discuss about it too.

Who to pass complex objects using "GET" to


actions?
Action: here we need to pass pageNo, pageSize and user object detail (Id, Name, Email)

Hide Copy Code


// GET: /User/Find/1/30 or
// GET: /User/Find
[HttpGet]
public JsonResult Find(int pageNo, int pageSize, User user)
{
var value = Request.QueryString["user"];
/*here we will not get user, beacuse mvc doesn't work like that*/
/*solution 1: rather than an object, use all properties of user object as parms
Find(int pageNo, int pageSize, long userId, string userName...)
*/
/*solution 2: use httppost, which is the most proper for the job*/
return Json("Response from Find", JsonRequestBehavior.AllowGet);
}

Try url value pass, but how to pass the user object in url? Lets try something like,
Result at action, pageNo: 3, pageSize: 5, user: null

Hide Copy Code


/*GET*/
$.ajax({
url: '/User/Find/3/5',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
data: { user: { name: 'Rintu', email: 'Rintu@gmial.com' } },
async: true,
processData: false,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});

Try value pass as object, like,


Result at action, pageNo: 2, pageSize: 20, user: null

Hide Copy Code


/*GET*/
$.ajax({
url: '/User/Find',
dataType: "json",
type: "GET",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: { pageNo: 2, pageSize: 20, user: { name: 'Rintu', email: 'Rintu@gmial.com' } },
async: true,
processData: true,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});

In both cases we were unable to pass to the values of user object

So how can we pass those values all together?


Solution 1: rather than an object, use all properties of user object as parms
Find(int pageNo, int pageSize, long userId, string userName...)
Solution 2: use httppost and POST, which is the most proper for the job

Limitations
1. Yes there could be something which I miss understood or presented. So if you find anything just let
me know.
2. All of these examples are not fully operational at real times projects yet. But used at prototype levels.

Find Visual Studio 2012 solution of MVC4 project at the attachment.

License
This article, along with any associated source code and files, is licensed under The Code Project Open
License (CPOL)

Share

S-ar putea să vă placă și