使用jQuery傳送物件JSON到ASP.NET MVC

過去介紹過用jQuery傳件物件陣列字串陣列到ASP.NET MVC,採取的格式一直都還是application/x-www-form-urlencoded,遇到物件陣列時會編碼成players[0][Id]=...&players[0][Name]=..;JSON是當今傳輸轉換格式的主流,比起Form UrlEncode更直覺易偵錯,如要進行客製有豐富的現成程式庫,是更佳的選擇。

要以JSON格式傳送物件給ASP.NET MVC,除POST內容需為JSON字串,更重要的是HTTP Header的Content-Type必須設為application/json,才能被正確識別並反序列化還原為Server端物件。$.post()並能指定contentType,因此需改用底層的$.ajax(),我習慣仿效$.post()寫成$.postJson(),差別只在於傳送的資料物件會經JSON.stringify()序列化並將contentType指定為appliction/json,其餘呼叫應用方式則與$.post()一致。

用個範例說明,要傳送的Player類別如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace Lab1219.Models
{
    public class Player
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime RegDate { get; set; }
        public int Score { get; set; }
 
        public string ToText()
        {
            return string.Format("I:{0} N:{1} R:{2:yyyy-MM-dd} S:{2:n0}",
                Id, Name, RegDate, Score);
        }
    }
}

View有兩點補充: 1) 先前提過的$.postJson()函式,用起來$.post()一模一樣   2) RegDate宣告日期時用Date.UTC()指定UTC時區。

 
@{
    Layout = null;
}
 
<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        <input type="button" id="bSend" value="Test" />
    </div>
    <script src="~/Scripts/jquery-2.0.3.js"></script>
    <script>
        //以application/json ContentType傳送JSON字串到Server端
        jQuery.postJson = function (url, data, callback, type) {
            if (jQuery.isFunction(data)) {
                type = type || callback;
                callback = data;
                data = undefined;
            }
 
            return jQuery.ajax({
                url: url,
                type: "POST",
                dataType: type,
                contentType: "application/json",
                data: typeof(data) == "string" ? data : JSON.stringify(data),
                success: callback
            });
        };
    </script>
    <script>
        $("#bSend").click(function () {
            var players = [{
                Id: 1000, Name: "Darkthread",
                RegDate: new Date(Date.UTC(2000, 0, 1)),
                Score: 32767
            }, {
                Id: 1024, Name: "Jeffrey",
                RegDate: new Date(Date.UTC(2000, 0, 1)),
                Score: 9999
            }];
 
            $.postJson("@Url.Content("~/home/send")", players, function (res) {
                alert(res);
            });
        });
    </script>
</body>
</html>

Controller方面只有一點補充,參數players前方要加上[FromBody] Attribute,請ASP.NET MVC由POST傳送的內容本體解析參數,餘下的工作細節ASP.NET MVC自會搞定。

using Lab1219.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
 
namespace Lab1219.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            return View();
        }
 
        public ActionResult Send([FromBody]Player[] players)
        {
            return Content(string.Join("\n",
                players.Select(o => o.ToText()).ToArray()));
        }
    }
}

執行結果如下,這樣就能實現以JSON格式傳送參數給ASP.NET MVC。

檢查傳送內容,驗明POST內容確實為JSON無誤,大功告成。

歡迎推文分享:
Published 23 December 2013 09:30 PM 由 Jeffrey
Filed under: ,



意見

# 小黑 said on 24 December, 2013 07:39 PM

請問黑大,

文中程式碼,有一段 "@Url.Content("~/home/send")",

測試中,若 JS 是使用 link 檔案的方式,似乎會失效,不知黑大是否有法可解?

# Jeffrey said on 26 December, 2013 12:36 AM

to 小黑,我常用的解法是在cshtml中加一段window.appRoot="@Url.Content("~/")",在JS中再取得appRoot變數組裝路徑,由於用到的地方很多,多半會再進一步提取寫成$.mapPath('~/blah')之類的共用函式。

# 小黑 said on 30 December, 2013 08:57 AM

謝謝黑大指點

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<December 2013>
SunMonTueWedThuFriSat
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234
 
RSS
【工商服務】
OrcsWeb: Windows Server Hosting
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication