題目讀來有點不知所云,用實例講解才會清楚。在ASP.NET MVC Controller端建立的物件,想在輸出View的同時轉成JavaScript端物件,最直覺的做法是將物件轉為JSON字串,再以Razor語法內嵌一段var dataItem = { "num_prop": 1234, "str_prop": "ABCD", "bool_prop": true }; JavaScript語法,直接建立JavaScript物件。
但這個做法遇上DateTime屬性會有個小問題,例如:
public ActionResult Edit()
{
var item = new ColorData()
{
Index = 255,
Name = "Dark",
ConvTime = DateTime.Now,
Rank = 1,
RGBCode = "#000000",
Remark = "Very very dark..."
};
ViewBag.DataItem = JsonConvert.SerializeObject(item);
return View();
}
View Edit.cshtml寫成:
<script>
var DataItem = @Html.Raw(ViewBag.DataItem);
</script>
得到結果為:
var DataItem = {"Index":255,"Name":"Dark","RGBCode":"#000000",
"ConvTime":"2016-06-28T21:09:15.2008013+08:00","Rank":1,
"Remark":"Very very dark..."};
JavaScript的ConvTime屬性型別為字串,而我們期望的是Date型別。JavaScript端要將ISO 8601格式字串轉Date型別,最常見做法是在JSON.parse()時傳入DateReviver函式。依此概念衍生出兩種解法:
- 將DataItem以JSON.stringify先轉成JSON字串,再用JSON.parse()+DateReviver轉回物件
- 改寫為ViewBag.DataItemJson = JsonConvert.SerializeObject(JsonConvert.SerializeObject(item))跟
var DataItemJson = @Html.Raw(ViewBag.DataItemJson);
改傳字串到View端後再用JSON.parse()+DateReviver轉為物件
方法雖然可行,為了解決日期問題,JSON轉來轉去,怎麼看都有點蠢。心想,如果產生JSON時,用new Date(nnnn)取代"yyyy-MM-ddTHH:mm:ssZ",不靠游擊手轉傳,表演從全壘打牆邊直傳本壘的雷射肩,這才叫帥氣。
查了資料,Json.NET不虧是天神級的JSON兵器,有個JavaScriptDateTimeConverter可以協助我們實現願望。在SerializeObject時傳入new JavaScriptDateTimeConverter()當參數:
public ActionResult Edit()
{
var item = new ColorData()
{
Index = 255,
Name = "Dark",
ConvTime = DateTime.Now,
Rank = 1,
RGBCode = "#000000",
Remark = "Very very dark..."
};
ViewBag.DataItem = JsonConvert.SerializeObject(item,
new JavaScriptDateTimeConverter());
return View();
}
JSON字串中的ConvTime屬性值由ISO 8601格式字串會被改成new Date(nnnn),拿來宣告JS物件就直接是Date型別囉!
又到了呼口號時間: