2011年10月31日 星期一

ASP.NET MVC, JSON資料的日期轉換與格式化 2


上一篇「ASP.NET MVC, JSON資料的日期轉換與格式化 1」說明了後端序列化的JSON日期資料要如何轉換以及格式化,

然而我們在後端所用的序列化JSON是直接使用ASP.NET MVC的預設內部方法,也就是用JavascriptSerializer來做序列化,

而之前有好幾篇文章也有說明到各種的在後端序列化的方式,

所以這一篇我們就來看看各種的序列化方式的JSON日期轉換與格式化。


首先我們先來看看要測試的前端畫面

image

會用五種方式來做測試,五種測試方式的結果都應該相同。

  1. Use Regular Expression and format date by f
  2. Use SubStr and format date by dateFormat(modified)
  3. Use SubStr and format date by f
  4. Use json4ms and format date by f
  5. Use json4ms and format date by jquery-dateFormat

 

使用JsonResult, and return Json() 方式

這是最基本的方式,首先來看看後端的程式:

public JsonResult GetNodesJson()
{
  var collection = service.GetCollection().OrderBy(x => x.CreateDate).Select(x => new
  {
    ID = x.ID,
    Name = x.Name,
    Sort = x.Sort,
    CreateDate = x.CreateDate,
    UpdateDate = x.UpdateDate
  });
  return Json(collection, JsonRequestBehavior.AllowGet);
}

接下來看看前端的Javascript的程式處理:

function LoadJsonData(convertMethod)
{
    $.ajax({
        url: '<%= Url.Action("GetNodesJson", "Test") %>',
        type: 'post',
        dataType: 'json',
        async: false,
        cache: false,
        success: function (data)
        {
            if (data)
            {
                var content = convertMethod;
 
                switch (convertMethod)
                {
                    case "LoadJsonData1":
                        content += " , " + $('#Button1').val() +" <br/><br/>";
                        break;
                    case "LoadJsonData2":
                        content += " , " + $('#Button2').val() +" <br/><br/>";
                        break;
                    case "LoadJsonData3":
                        content += " , " + $('#Button3').val() +" <br/><br/>";
                        break;
                    case "LoadJsonData4":
                        content += " , " + $('#Button4').val() +" <br/><br/>";
                        break;
                    case "LoadJsonData5":
                        content += " , " + $('#Button5').val() +" <br/><br/>";
                        break;
                }
 
                $.each(data, function (i, item)
                {
                    content += "Name: " + item.Name;
                    content += " || CreateDate: " + item.CreateDate;
                    switch (convertMethod)
                    {
                        case "LoadJsonData1":
                            content += " || CreateDate(Formatted): " + ConvertWithRegex(item.CreateDate) + "<br>";
                            break;
                        case "LoadJsonData2":
                            content += " || CreateDate(Formatted): " + ConvertWithdateFormat(item.CreateDate) + "<br>";
                            break;
                        case "LoadJsonData3":
                            content += " || CreateDate(Formatted): " + ConvertWithF(item.CreateDate) + "<br>";
                            break;
                        case "LoadJsonData4":
                            content += " || CreateDate(Formatted): " + ConvertWithJson4msAndF(item.CreateDate) + "<br>";
                            break;
                        case "LoadJsonData5":
                            content += " || CreateDate(Formatted): " + ConvertWithJson4msAndjqueryDateFormat(item.CreateDate) + "<br>";
                            break;
                    }
                });
                $('#JsonContent').html(content);
            }
        }
    });
}
 
function ConvertWithRegex(jsonDate, formatString)
{
    if ($.trim(formatString).length == 0)
    {
        formatString = "yyyy-MM-dd HH:mm:ss";
    }
    return (eval(jsonDate.replace(/\/Date\((.*?)\)\//gi, "new Date($1)"))).f(formatString);
}
 
function ConvertWithdateFormat(jsonDate, formatString)
{
    if ($.trim(formatString).length == 0)
    {
        formatString = "yyyy-MM-dd HH:mm:ss";
    }
    return (new Date(parseInt(jsonDate.substr(6)))).format(formatString);
}
 
function ConvertWithF(jsonDate, formatString)
{
    if ($.trim(formatString).length == 0)
    {
        formatString = "yyyy-MM-dd HH:mm:ss";
    }
    return new Date(parseInt(jsonDate.substr(6), 10)).f(formatString);
}
 
function ConvertWithJson4msAndF(m, formatString)
{
    if ($.trim(formatString).length == 0)
    {
        formatString = "yyyy-MM-dd HH:mm:ss";
    }
    return JSON.parseWithDate(JSON.stringifyWcf(m)).f(formatString);
}
 
function ConvertWithJson4msAndjqueryDateFormat(m, formatString)
{
    if ($.trim(formatString).length == 0)
    {
        formatString = "yyyy-MM-dd HH:mm:ss";
    }
    return $.format.date(JSON.parseWithDate(JSON.stringifyWcf(m)), formatString);
}

執行結果:

image

image

image

image

image

不管是用哪一種轉換JSON日期資料與日期格式化的方式,所得到的結果都是一樣的。

 

使用Json.NET, JsonConvert.SerializeObject()方式

這個方式就是在後端使用Json.NET來對資料做序列化的操作,看看程式的內容:

public ActionResult GetNodesJsonByJsonNet()
{
  var collection = service.GetCollection().OrderBy(x => x.CreateDate);
  JArray ja = new JArray();
  foreach (var item in collection)
  {
    JObject jo = new JObject();
    jo.Add("ID", item.ID.ToString());
    jo.Add("Name", item.Name);
    jo.Add("Sort", item.Sort);
    jo.Add("CreateDate", item.CreateDate);
    jo.Add("UpdateDate", item.UpdateDate);
    ja.Add(jo);
  }
  return Content(JsonConvert.SerializeObject(ja), "application/json");
}

而前端程式的部份,除了使用後端Controller/Action的地方不一樣之外,其餘的都一樣,所以就不用再貼出程式。

以下是各種前端處理方式的執行結果:

image

image

image

image

image

上面五個方式的執行結果,如果有仔細的去比對,可以看出來第一個結果與其他四個的執行結果是有些不一樣的,

以下面的圖在與上面的突來做個比較,

image

可以看到第一個用正則式來解析 \/Date(Tick)\/ 的資料後再去轉為日期物件,有些結果會多個一秒,

再來看看原始的資料:

image

在前端使用正則式來解析 \/Date(Tick)\/ 資料後再轉換日期最後做日期格式化(不論是用哪一種格式化方法)

milliseconds在200ms以上都會做進位的動作,所以要注意一下這個地方的差異。

 

使用JsonResult, return CustomJson() , EFSimpleJavascriptSerializer, EFJavascriptSerializer 方式

後端的程式:

這邊的後端程式比較簡潔,因為使用EFSimpleJavascriptSerializer與EFJavascriptSerializer不用再做指定物件欄位的動作,

public JsonResult GetNodesJsonByCutsomJson()
{
  var collection = service.GetCollection().OrderBy(x => x.CreateDate);
  return CustomJson(collection, JsonRequestBehavior.AllowGet);
}

而前端程式的部份,除了使用後端Controller/Action的地方不一樣之外,其餘的都一樣,所以就不用再貼出程式。

以下是各種前端處理方式的執行結果:

image

image

image

image

image

這個方式的執行結果都是一樣的,也與第一個方式的結果是一致的。

 

另外就是,如果你會覺得總是需要單獨對後端所產生的JSON資料裡的日期做轉換處理會很麻煩,

其實也可以使用json4ms.js對整個JSON資料去做轉換,而當資料內是為日期時,就會去做轉換,而其他的資料不會影響到,

前端程式的內容如下:

  function LoadJsonDataStandalone()
  {
    $.ajax({
      url: '<%= Url.Action("GetNodesJson", "Test") %>',
      type: 'post',
      dataType: 'json',
      async: false,
      cache: false,
      success: function (data)
      {
        if (data)
        {
          var jsonData = JSON.parseWithDate(JSON.stringifyWcf(data));
          var content = $('#Button6').val() + " <br/><br/>";
          $.each(jsonData, function (i, item)
          {
            content += "Name: " + item.Name;
            content += " || Sort: " + item.Sort;
            content += " || CreateDate: " + item.CreateDate;
            content += " || CreateDate(Formatted): " + item.CreateDate.f("yyyy-MM-dd HH:mm:ss");
            content += "<br/>";
          });
          $('#JsonContent').html(content);
        }
      }
    });
  }

可以看到程式中,先把後端傳回來的JSON資料先做JSON.stringifywfc()的轉換後,再用JSON.parseWithDate()去做日期資料的解析,

如此一來,原本的的CreateDate資料就會轉換成GMT的日期格式,如果有需要的話,還可以使用格式化套件去轉乘我們要的日期格式。

執行結果:

image

 

延伸閱讀:

使用Entity Framework 將物件轉為JSON時遇到循環參考錯誤 3
ASP.NET MVC + JSON 自定義JsonResult 2
ASP.NET MVC, JSON資料的日期轉換與格式化 1


 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。