網頁

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


 

以上

沒有留言:

張貼留言