2013-02-28 48 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