2013-02-28 84 views
6

目前,我有一個類,它看起來是這樣的:如何自定義JSON序列化?

public class TestSerilizer 
{ 
    public int IntValue; 
    public DateTime DTValue; 
} 

而且該類序列化返回JSON一個控制器,它看起來是這樣的:

public ActionResult TestJson() 
{ 
    TestSerilizer testDT = new TestSerilizer(); 
    return Json(testDT); 
} 

衆所周知,這產生在JSON中看起來像/Date(123456)/的日期並不理想。爲了我的目的,我希望能夠添加一個屬性,以我的視圖有意義的方式格式化日期。理想情況下,我想改變我的視圖模型看起來是這樣的:

public class TestSerilizer 
{ 
    public int IntValue; 
    [JSONDateFormatter("hh:mm tt")] 
    public DateTime DTValue; 
} 

將產生與格式化的日期JSON數據。有沒有辦法劫持JSON序列化來做類似的事情?應該指出的是,這是一個很大的代碼庫,它既包含這個隱式的JSON序列化,也顯式使用了JavaScriptSerializer類,所以我更喜歡一種適用於這兩種情況的方法,但我明白這可能是不可能的。

+0

日期是JSON特別凝灰岩。我通常把它們當作字符串,並嘗試以javascript方式嘗試解釋或管理它們的方式發送它們。 – 2013-02-28 16:21:54

回答

7

這通常是我如何管理我的對象的日期序列化。請注意,這裏使用DataMember屬性,因爲它需要通過二進制和JSON可序列化:

[DataContract] 
[Serializable] 
public class YourClass 
{ 
     [DataMember] 
     private long timeStampLong; 


     [IgnoreDataMember] 
     public DateTime TimeStamp 
     { 
      get { return new DateTime(timeStampLong); } 
      set { timeStampLong = value.Ticks; } 
     } 
} 

現在,這可能不會讓日期時間的JSON的可讀性,但它將使一致。不同的json庫處理序列化日期時間的方式不同,因此您希望能夠強制它們以相同的方式序列化。

編輯:請注意,這不是C#屬性意義上的第二個屬性,但只是該屬性的基礎字段。您可以將底層字段替換爲字符串,並且該底層字段不會暴露在對象之外。由於IgnoreDataMember您仍然只是序列化一個單一的值。

Edit2:當有人需要實現這個時,添加了類聲明以獲得更完整的答案。

編輯:對於一個更完整的示例我想我將包括在該響應我已經使用的其它選項(使用一個字符串作爲支持字段)

/// <summary> 
    /// Representations of the TimeStamp used for serialization 
    /// </summary> 
    [DataMember(Name = "TimeStamp")] 
    private String timeStamp; 

    /// <summary> 
    /// timestamp when the request is sent 
    /// </summary> 
    [IgnoreDataMember] 
    public DateTime TimeStamp 
    { 
     get { return DateTime.Parse(timeStamp, null, DateTimeStyles.RoundtripKind); } 
     set { timeStamp = value.ToUniversalTime().ToString("o"); } 
    } 
+0

這就是光滑的...必須嘗試一下 – 2013-02-28 16:34:00

+1

我們有一個系統需要支持多個json庫(因爲我們不知道我們的客戶端將使用什麼),所以這種方式無關緊要,如果你使用.net序列化程序,或newtonsoft或其他一些JSON序列化程序,它總是隻會序列化長整型值。 – jzworkman 2013-02-28 16:43:16

+0

我希望避免擁有第二個屬性,但越來越像這樣做是不可能的。 – Mykroft 2013-02-28 18:11:41

0

正如@jzworkman指出的那樣,該技術輪廓是如何控制內部DateTime值如何序列化的。我堅持總是使用一種基於字符串的格式,可以通過任何其他方式可靠地解析它。如果可能的話,我堅持使用可以正確處理時區映射的ISO 8601格式。在C#中,你可以使用myDateTimeValue.ToString(「O」)獲得的日期時間字符串中的ISO 8601

Wikipedia article on ISO 8601