讀者小黑提問:使用jQuery.ajax傳送物件陣列給ASP.NET MVC一文已示範如何使用jQuery.post()傳遞List<Player>到ASP.NET MVC,但依該做法傳送List<string>卻無法成功,應如何解決?
熬不住手癢,就來動手實測玩看看吧!改寫前文的MVC Action,加入接收string[] mylist參數,同時結果改為players及mylist一併回傳:
///測試用Action,前端接入List<Player>,轉JSON後傳回
public ActionResult Update(List<Player> players, string[] mylist)
{
return Json(new
{
P = players,
L = mylist
});
}
前端程式也得稍做修改,postMvc()時多傳送mylist字串陣列,data參數改為{ players: array, mylist: list }:
如小黑所言,MVC端未接收到mylist,呈現null。
使用瀏覽器偵錯工具檢查POST內容,mylist陣列被轉為兩個欄位名稱為mylist[]的參數。
陣列元素命名成arrayName[]似乎是PHP慣例,故被jQuery選為預設.ajax()編碼規則,但顯然與ASP.NET MVC不同。印象中看過?ary=1&ary=2&ary=3的URL參數陣列表示法,加上ASP.NET MVC需將player[0][Id]改成player[0].Id的經驗,直覺認定mylist[]改成mylist可過關,因此補上一段.replace(/%5B%5D=/g, "="),將所有blah[]=改為blah=應該就搞定了。
重新測試,欄位名稱修改成功!
MVC端也一如預期順利接到mylist字串陣列囉~
不過,以上做法有點Hacking。jQuery要傳送多個複雜參數給ASP.NET MVC,其實有更簡單的做法 - 用JSON格式就對了!
如以下範例,我寫了一個postJson()方法,只有兩個重點:將contentType設為application/json,data內容則改為JSON.stringify(data)。應用時以postJson()取代postMvc(),其餘不變:
<script>
(function ($) {
$.extend($, {
postJson: function (url, data, succ) {
return $.ajax({
url: url,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
dataType: "json",
success: succ
});
}
});
})(jQuery);
$(function () {
var array = [], list = ["Jeffrey", "Darkthread"];
array.push({ Id: "P01", Name: "Jeffrey" });
array.push({ Id: "P02", Name: "Darkthread" });
$.postJson(
"@Url.Content("~/AjaxPost/Update")",
{ players: array, mylist: list },
function(res) {
alert(JSON.stringify(res));
},
"json"
);
});
</script>
如此,jQuery會以application/json Content-Type送出data資料物件的JSON字串(包含players及mylist兩個屬性)。當ASP.NET MVC偵測到Request Content-Type為application/json,會執行JSON反序列化,並取出其中的players與mylist,對應到Update(List<Player> players, List<string> mylist)的兩個參數,完成參數傳遞。
相形之下,採用JSON格式傳送不必擔心 beforeSend 遺漏轉換邏輯,再複雜的物件都能轉換,會是較簡潔可靠的做法,可優先考慮。