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
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
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")
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 let’s 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;
- 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
- 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.
- 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 data’s 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 data’s.
- At the success attribute we will get the response data’s.
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
- 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.
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
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. Let’s 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');
}
});
Let’s 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.
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.
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? Let’s try something like,
Result at action, pageNo: 3, pageSize: 5, user: null
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
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
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
- Yes there could be something which I miss understood or presented. So if you find anything just let me know.
- 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.
No comments:
Post a Comment