Introduction
In ASP.NET MVC, we have seen http verbs like HttpGet
, HttpPost
, HttpPut
and HttpDelete
. Here, we will see how we can use these words in actions, what do these words mean, and how we can use jquery ajax calls for such http verb enable actions.
Why Use HttpVerbs?
Let's examine these actions:
UrlResponse()
- Is accessible using browser url
- It can also be used for Ajax calls
public JsonResult UrlResponse()
{
return Json(new { Name = "UrlResponse", Response = "Response from Get",
Date = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") }, JsonRequestBehavior.AllowGet);
}
TypedResponse()
- It can only be usable using Ajax calls using (type: "
GET
") - If trying to access using browser url, it would throw an error
[HttpGet]
public JsonResult TypedResponse()
{
return Json(new { Name = "TypedResponse", Response = "Response from Get",
Date = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt") }, JsonRequestBehavior.AllowGet);
}
MultipleTypedResponse()
- If trying to access using browser url, it would throw an error
- It can only be usable using Ajax calls using (type: "
GET
"/"POST
")
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.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 let’s see how we can use http verbed actions in MVC, and Jquery Ajax calls using $.ajax
objects together. But there are some concerns with:
- 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',
- 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",
- How to pass parameters to that action if needed.
- At
data
attribute, we specify the data to be passed to a particular action.
data: JSON.stringify({ user: { name: 'Rintu', email: 'Rintu@gmial.com' } }),
data: { name: 'Rintu', email: 'Rintu@gmial.com' },
- For GET requests, we can also specify the data 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',
- Where to find the response data.
At the success attribute, we will get the response data.
success: function (data) {
alert(data);
},
- Is there any error?
At the error attribute, we will get error detail, if any found at the server end:
error: function (xhr) {
alert('error');
}
HttpGet
MVC Action
[HttpGet]
public JsonResult Get(int id)
{
return Json("Response from Get", JsonRequestBehavior.AllowGet);
}
Ajax Call
- passing value of id as url: '/User/Get/20'
- no use of data attr at the Ajax object
$.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
[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:
$.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
[HttpPut]
public JsonResult Edit(int id, User user)
{
return Json("Response from Edit");
}
Ajax Call
$.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
[HttpDelete]
public JsonResult Delete(int id)
{
return Json("Response from Delete");
}
Ajax Call
$.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. Let’s just talk about them too.
Let's Take Some Closer Looks for GETs
When we are working with httpGet
verbed actions, we may face concerns like:
Pass Data as Objects Rather Than JSON.stringify(object)
Action
[HttpGet]
public JsonResult Contains(string name, string email)
{
return Json("Response from Contains", JsonRequestBehavior.AllowGet);
}
Ajax Call
$.ajax({
url: '/User/Contains',
dataType: "json",
type: "GET",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: { name: 'Rintu', email: 'Rintu@gmial.com' },
async: true,
processData: true,
cache: false,
success: function (data) {
alert(data);
},
error: function (xhr) {
alert('error');
}
});
Let’s find some differences with the previous HttpGet
verb use.
At the old one, we have used:
- url: '/User/Get/20'
- There was no data attribute at the Ajax object.
At this one, we have used:
- url: '/User/Create'
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
[HttpGet]
public JsonResult Find(int pageNo, int pageSize, User user)
{
return Json("Response from Find", JsonRequestBehavior.AllowGet);
}
Ajax Call
$.ajax({
url: '/User/Find/3/5',
dataType: "json",
type: "GET",
contentType: 'application/json; charset=utf-8',
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 of 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
):
[HttpGet]
public JsonResult Find(int pageNo, int pageSize, User user)
{
var value = Request.QueryString["user"];
return Json("Response from Find", JsonRequestBehavior.AllowGet);
}
Try url
value pass, but how to pass the user
object in url
? Let’s try something like:
Result at action, pageNo
: 3
, pageSize
: 5
, user
: null
$.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
$.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 appropriate for the job
Limitations
- Yes, there could be something that I misunderstood or mispresented. So if you find anything, just let me know.
- All of these examples are not fully operational in real time projects yet, but they have been used at prototype levels.
Find the Visual Studio 2012 solution of MVC4 project in the attachment.