6

目前我有一个看起来像这样的类:

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

和一个控制器,该控制器将该类序列化为 JSON,如下所示:

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

众所周知,这会产生一个看起来有点像/Date(123456)/JSON 的日期,这是不太理想的。出于我的目的,我希望能够添加一个属性,该属性将以对我的观点有意义的方式格式化我的日期。理想情况下,我想将我的视图模型更改为如下所示:

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

这将生成带有格式化日期的 JSON 数据。有没有办法劫持 JSON 序列化来做类似的事情?应该注意的是,这是一个大型代码库,它同时具有这种隐式 JSON 序列化和JavaScriptSerializer类的显式使用,因此我更喜欢一种适用于这两种情况的方法,但我知道这可能是不可能的。

4

2 回答 2

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"); }
    }
于 2013-02-28T16:28:54.657 回答
0

正如@jzworkman 指出的那样,该响应中的技术大纲是如何控制内部 DateTime 值如何被序列化。我坚持始终使用基于字符串的格式,该格式几乎可以被其他任何东西可靠地解析。如果可能的话,我坚持使用可以正确处理时区映射的 ISO 8601 格式。在 C# 中,您可以使用 myDateTimeValue.ToString("o") 获取 ISO 8601 中 DateTime 的字符串。

维基百科关于 ISO 8601 的文章

于 2013-02-28T17:14:40.187 回答