在 ASP.NET MVC 中使用 Jquery Ajax 执行 GET、POST、PUT、DELETE






4.67/5 (34投票s)
在 ASP.NET MVC 中使用 Jquery Ajax 执行 GET、POST、PUT、DELETE
引言
在 ASP.NET MVC 中,我们已经看到了像 HttpGet、HttpPost、HttpPut 和 HttpDelete 这样的 HTTP 动词。在这里,我们将看到如何在操作中使用这些动词,这些动词的含义是什么,以及如何使用 jQuery Ajax 调用来调用启用这些 HTTP 动词的操作。
为什么要使用 HttpVerbs?
让我们来分析一下这些操作
UrlResponse()
- 可以通过浏览器 URL 访问
- 也可以用于 Ajax 调用
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()
- 只能通过 Ajax 调用使用 (type: "GET")
- 如果尝试通过浏览器 URL 访问,将会引发错误
[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()
- 如果尝试通过浏览器 URL 访问,将会引发错误
- 只能通过 Ajax 调用使用 (type: "GET"/"POST")
[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);
}
现在,让我们看看如何在 MVC 和 Jquery Ajax 调用中使用带 HTTP 动词的操作,并结合 $.ajax 对象。但是,有一些问题需要考虑
- 如何为 Ajax 调用指定特定操作。在 url属性中,使用/{controller}/{action}模式指定控制器和操作url: '/User/Create', url: '/User/Get/20', 
- 如何在 Ajax 调用中指定 HTTP 动词在 Ajax 对象的 type属性中,值为GET/POST/PUT/DELETEtype: "POST", type: "GET", 
- 如果需要,如何将参数传递给该操作。- 在 data属性中,指定要传递给特定操作的数据。data: JSON.stringify({ user: { name: 'Rintu', email: 'Rintu@gmial.com' } }),data: { name: 'Rintu', email: 'Rintu@gmial.com' },
- 对于 GET 请求,我们也可以在 url属性中指定数据,但需要处理路由配置。(在这里,我们避免处理与路由配置相关的事务)。
 url: '/User/Get/20', 
- 在 
- 在哪里可以找到响应数据。在 success 属性中,我们将获得响应数据。 success: function (data) { alert(data); },
- 有没有错误?在 error 属性中,如果服务器端发现任何错误,我们将获得错误详情 error: function (xhr) { alert('error'); }
HttpGet
MVC 操作
// GET: /User/Get/5
[HttpGet]
public JsonResult Get(int id)
{
    return Json("Response from Get", JsonRequestBehavior.AllowGet);
}
Ajax 调用
- 将 id 值作为 url 传递:'/User/Get/20'
- Ajax 对象中的 data 属性未使用
/*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 操作
// POST: /User/Create
[HttpPost]
public JsonResult Create(User user)
{
    return Json("Response from Create");
}
Ajax 调用
数据通过 Ajax 对象的 data 属性传递给操作
/*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 操作
// PUT: /User/Edit
[HttpPut]
public JsonResult Edit(int id, User user)
{
    return Json("Response from Edit");
}
Ajax 调用
/*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 操作
// DELETE: /User/Delete
[HttpDelete]
public JsonResult Delete(int id)
{
    return Json("Response from Delete");
}
Ajax 调用
/*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');
    }
});
嗯,它们都工作得很好,但也有一些有趣的事情。我们也可以聊聊它们。
让我们更仔细地看看 GET
当我们处理 httpGet 动词化的操作时,可能会遇到以下问题:
将数据作为对象传递,而不是使用 JSON.stringify(object)
操作
// GET: /User/Contains
[HttpGet]   //use or not works same
public JsonResult Contains(string name, string email)
{
    return Json("Response from Contains", JsonRequestBehavior.AllowGet);
}
Ajax 调用
/*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');
    }
});
让我们找一下与之前 HttpGet 动词用法的一些区别。
在旧的用法中,我们使用了
- url: '/User/Get/20'
- Ajax 对象中没有 data 属性。
在这个用法中,我们使用了
- url: '/User/Create'
- data: { name: 'Rintu', email: 'Rintu@gmial.com' }
这样就能正常工作。
如果我们尝试同时使用 URL 和 Data 传递值会怎么样?
操作
// 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 调用
/*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');
    }
})
在操作中,pageNo 和 pageSize 将是 1 和 30,而不是 2 和 20,因为 URL 数据传递的优先级更高。
这种带有 URL 中数据的 "GET" 请求有助于操作重载。在这种情况下,我们需要注意路由配置。
是的,这里的用户对象还有另一个问题,我们也将讨论它。
如何使用 "GET" 将复杂对象传递给操作?
操作:在这里,我们需要传递 pageNo、pageSize 和用户对象详情 (Id、Name、Email)
// 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);
}
尝试通过 url 值传递,但如何将 user 对象传递到 url?让我们试试
操作中的结果,pageNo: 3,pageSize: 5,user: null
/*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');
    }
});
尝试作为对象传递值,例如
操作中的结果,pageNo: 2,pageSize: 20,user: null
/*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');
    }
});
在这两种情况下,我们都无法将 user 对象的值传递过去。
那么,我们如何才能一次性传递这些值呢?
解决方案 1:与其传递对象,不如将用户对象的所有属性作为参数传递
Find(int pageNo, int pageSize, long userId, string userName...)
解决方案 2:使用 httppost 和 POST,这是最适合这项工作的
限制
- 是的,可能有一些我误解或错误表达的地方。所以,如果您发现任何问题,请告诉我。
- 所有这些示例尚未在实际项目中完全运行,但它们已被用于原型级别。
在附件中查找 MVC4 项目的 Visual Studio 2012 解决方案。


