博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]使用jQuery.ajax傳送物件陣列給ASP.NET MVC
阅读量:5998 次
发布时间:2019-06-20

本文共 5895 字,大约阅读时间需要 19 分钟。

本文转自:

在ASP.NET MVC裡,我們可以用物件集合當成Action的傳入參數,例如以下範例:

排版顯示
純文字
複製文字
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MvcMobileLab.Controllers
{
public class AjaxPostController : Controller
{
public ActionResult Index(string viewName)
{
if (string.IsNullOrEmpty(viewName))
return View();
else
return View(viewName);
}
/// 
/// 測試用資料類別
/// 
public class Player
{
public string Id { get; set; }
public string Name { get; set; }
}
///測試用Action,前端接入List
,轉JSON後傳回
public ActionResult Update(List
players)
{
return Json(players);
}
}
}
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcMobileLab.Controllers { public class AjaxPostController : Controller { public ActionResult Index(string viewName) { if (string.IsNullOrEmpty(viewName)) return View(); else return View(viewName); } /// <summary> /// 測試用資料類別 /// </summary> public class Player { public string Id { get; set; } public string Name { get; set; } } ///測試用Action,前端接入List<Player>,轉JSON後傳回 public ActionResult Update(List<Player> players) { return Json(players); } } }

在以上的Controller裡,定義了一個極簡單的Player資料類別,只有Id跟Name兩個屬性。假設有一個Update動作,可接收List<Player>作為輸入參數,為了示範,並不真的把players資料更新到資料庫,而是轉為JSON格式後回傳,讓前端驗證資料是否已正確傳達。

在HTML Form裡要怎麼把List<Player>當成參數傳給Action呢? ASP.NET MVC內建的Model Binder已具備將特定規則參數對應成ICollection<T>的能力,方法可參考以下兩篇文章:

  • Phil Haack:
  • Scott Hanselman:

簡單來說,ASP.NET MVC的Model Binder會從POST的欄位中用players[0].Id, players[0].Name去找players陣列第一個物件的各屬性,用players[1].*去對應第二個物件... 以此類推。因此,如果我們想用jQuery.ajax()呼叫Update(List<Player> players) Action,只要用{ "players[0].Id": "P01", "players[0].Name": "Jeffrey", "players[1].Id": "P02" ... }當成參數傳送,ASP.NET MVC就能正確解析與接收,例如以下範例:

排版顯示
純文字
複製文字
@{ Layout = null; }
 
 
 
 
Test
$(function () {
var data = {
"players[0].Id": "P01",
"players[0].Name": "Jeffrey",
"players[1].Id": "P02",
"players[1].Name": "Darkthread"
};
$.post("@Url.Content("~/AjaxPost/Update")", data, function(res) {
alert(JSON.stringify(res));
}, "json");
});
 
 
 
 
 
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Test</title> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.js"></script> <script> $(function () { var data = { "players[0].Id": "P01", "players[0].Name": "Jeffrey", "players[1].Id": "P02", "players[1].Name": "Darkthread" }; $.post("@Url.Content("~/AjaxPost/Update")", data, function(res) { alert(JSON.stringify(res)); }, "json"); }); </script> </head> <body> </body> </html>

執行成功,前端可正確接回預期的List<Player>內容,驗證了用這種格式組合參數,ASP.NET MVC就能將我們傳送的內容解析成List<Player>!

不過,在大量使用Javascript的網頁中,通常會用陣列來保存Player物件,例如: var players = [ { Id:"P01", Name:"Jeffrey" }, { Id:"P02", Name: "Darkthread" } ],不太可能寫成<input type="text" name="players[0].Id" />的形式。因此,較直覺得的寫法應是$.post(the_action_url, { players: players_array }, function(r) { … }, "json");,這樣能成功嗎?

排版顯示
純文字
複製文字
@{ Layout = null; }
 
 
 
 
Test
$(function () {
var array = [];
array.push({ Id: "P01", Name: "Jeffrey" });
array.push({ Id: "P02", Name: "Darkthread" });
$.post(
"@Url.Content("~/AjaxPost/Update")",
{  players: array },
function(res) {
alert(JSON.stringify(res));
},
"json"
);
});
 
 
 
 
 
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Test</title> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.js"></script> <script> $(function () { var array = []; array.push({ Id: "P01", Name: "Jeffrey" }); array.push({ Id: "P02", Name: "Darkthread" }); $.post( "@Url.Content("~/AjaxPost/Update")", { players: array }, function(res) { alert(JSON.stringify(res)); }, "json" ); }); </script> </head> <body> </body> </html>

結果很有趣,ASP.NET MVC判讀出它是個陣列,但是Player的屬性值沒抓到,都是null。

實際觀察$.post()傳送的內容,可看出一些端倪...

$.ajax()遇到傳送參數中有物件陣列時,也會拆解成palyers[0],players[1]的形式,但對於屬性值,並不是ASP.NET MVC所預期的players[0].Id,而是寫成players[0][Id]。追進jQuery原始碼,發現這是function buildParams( prefix, obj, traditional, add )被賦與的編碼邏輯,且沒有預留自訂規則的空間。由於players[0].Id與players[0][Id]只有格式上的些微差異,因此我想到一個做法是在jQuery.ajax()的beforeSend事件做手腳,將序列化完成字串中的players[0][Id]用Regular Expression置換成players[0].Id,於是順手寫了一個Plugin, $.postMvc(),攔截beforeSend事件,對buildParams()序列化後的字串進行陣列元素屬性名稱的置換,再傳送出去。要應用時,用$.post它來取代$.post()即可:

排版顯示
純文字
複製文字
@{ Layout = null; }
 
 
 
 
Test
(function ($) {
$.extend($, {
//Replace item[0][propName] to item[0].propName for MVC model binder
postMvc: function (url, data, succ, dataType) {
return $.ajax({
url: url,
type: "POST", dataType: dataType,
data: data,
success: succ,
beforeSend: function (xhr, settings) {
settings.data =                              settings.data.replace(/%5D%5B(.+?)%5D=/g, "%5D.$1=");
}
});
}
});
})(jQuery);
 
$(function () {
var array = [];
array.push({ Id: "P01", Name: "Jeffrey" });
array.push({ Id: "P02", Name: "Darkthread" });
$.postMvc(
"@Url.Content("~/AjaxPost/Update")",
{  players: array },
function(res) {
alert(JSON.stringify(res));
},
"json"
);
});
 
 
 
 
 
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Test</title> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.js"></script> <script> (function ($) { $.extend($, { //Replace item[0][propName] to item[0].propName for MVC model binder postMvc: function (url, data, succ, dataType) { return $.ajax({ url: url, type: "POST", dataType: dataType, data: data, success: succ, beforeSend: function (xhr, settings) { settings.data = settings.data.replace(/%5D%5B(.+?)%5D=/g, "%5D.$1="); } }); } }); })(jQuery); $(function () { var array = []; array.push({ Id: "P01", Name: "Jeffrey" }); array.push({ Id: "P02", Name: "Darkthread" }); $.postMvc( "@Url.Content("~/AjaxPost/Update")", { players: array }, function(res) { alert(JSON.stringify(res)); }, "json" ); }); </script> </head> <body> </body> </html>

這樣子,就能很輕鬆地將Javascript物件陣列抛給ASP.NET MVC當List<T>參數囉~

歡迎推文分享:

 

转载地址:http://eawmx.baihongyu.com/

你可能感兴趣的文章
笑对人生,坐看云起云落
查看>>
面向对象
查看>>
连接池并发的实现原理
查看>>
HDU - 3966-Aragorn' Story(树链剖分+线段树)
查看>>
【BZOJ1101】Zap [莫比乌斯反演]
查看>>
online_judge_1473
查看>>
1970.1.1这个特殊时间
查看>>
将定时任务cron 解析成中文
查看>>
docker之docker-machine用法
查看>>
Alpha Scrum 3–Sep29,2011
查看>>
帧动画(wifi信号动态动画)
查看>>
IIS 7启用static JSON文件能POST方法
查看>>
P5205 【模板】多项式开根
查看>>
matlab练习3
查看>>
微博mini for Windows Phone 8 开发那些事
查看>>
redis文章索引
查看>>
OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE-2016-6210)
查看>>
Javascript回调函数
查看>>
Java 之封装
查看>>
可能是最简单的面向对象入门教程(二)为什么要有类型
查看>>