本範例展示如何透過jQuery.post傳送string[]參數給ASP.NET MVC。

情境模擬訊息發送操作,提供網頁介面供使用者挑選接收者(採用複選式下拉選單)、輸入發送內容後按鈕傳送訊息給指定對象。

ASP.NET MVC Controller如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace Mvc.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }
 
        public ActionResult SendMessage(string[] users, string message)
        {
            //假裝發通知給指定的使用者, 此處省略
            return Content(string.Format("已傳送訊息給{0}",
                users == null ? "null" : string.Join(",", users)));
        }
    }
}

至於前端,輸入欄位借重Knockout幾行搞定,按鈕動作則透過jQuery.post()以AJAX方式呼叫Controller的SendMessage方法,其中的users參數在C#端宣告型別為string[],Client端靠Knockout的下拉選單複選繫結selectedOptions直接取得使用者挑選的字串陣列,依直覺寫成{ users: vm.selUsers() }將字串陣列傳至Server端。

 
@{
    Layout = null;
}
 
<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
    <script src="~/Scripts/jquery-2.0.3.js"></script>
    <script src="~/Scripts/knockout-3.0.0.debug.js"></script>
</head>
<body>
    <div>
        <input type="text" data-bind="value: msg" />
        <input type="button" data-bind="click: sendMsg" value="Send Message" />
        <br /> 
        <select data-bind="options: users, selectedOptions: selUsers" multiple></select>
    </div>
    <script>
        function myViewModel() {
            var self = this;
            self.msg = ko.observable("Test");
            self.users = ko.observableArray(
                ["Jeffrey", "Darkthread", "Admin", "Guest"]);
            self.selUsers = ko.observableArray();
            self.sendMsg = function () {
                $.post("@Url.Content("~/home/sendmessage")",
                    { users: vm.selUsers(), msg: vm.msg() },
                    function (res) {
                        alert(res);
                    });
            };
        }
        var vm = new myViewModel();
        ko.applyBindings(vm)
    </script>
</body>
</html>

事與願違,ASP.NET MVC端的輸入參數string[]沒接到值,users為null:

用IE Dev Tool檢視傳送內容,可以發現jQuery.post()自動將字串陣列序列化為users[]=...&users[]=...(上圖黃底部分,%5B%5D是"["與"]"的UrlEncode編碼),但ASP.NET MVC卻認不得,所幸,我們離接通只差一小步。

關於陣列參數的序列化形式,傳統採用a=..&a=..格式,後來如PHP、Ruby on Rails等Framework改採a[]=..&a[]=..格式,jQuery從1.4版起便將陣列序列化預設格式改為a[]=..,但仍提供traditional參數可指定採用舊格式。而ASP.NET MVC仍採a=..&a=..格式,所以只需將傳遞參數交給$.param()轉換並指定traditional參數為true: $.param({ users: vm.selUsers(), msg: vm.msg() }, true), 問題就解決囉!

PS: 如對陣列化序列格式有興趣深入了解,可以參考jQuery.param()文件


Comments

Be the first to post a comment

Post a comment