【问题标题】:Serialize NodaTime JSON序列化 NodaTime JSON
【发布时间】:2013-01-25 23:53:55
【问题描述】:

与 BCL 的 DateTime 相比,我正在制作 NodaTime 的原型项目,但执行此结果会导致我出现 recursionLimit 超出错误。

这是我用来 JSON 化我的视图模型的函数。该函数返回后发生错误。

    [HttpPost]
    public JsonResult GetDates(int numOfDatesToRetrieve)
    {
        List<DateTimeModel> dateTimeModelList = BuildDateTimeModelList(numOfDatesToRetrieve);

        JsonResult result = Json(dateTimeModelList, JsonRequestBehavior.AllowGet);
        return result;
    }

当我检查它时,我的视图模型是正确构建的。 这是我的视图模型的代码。

public class DateTimeModel
{
    public int ID;

    public LocalDateTime NodaLocalDateTimeUTC;
    public LocalDateTime NodaLocalDateTime
    {
        get
        {
            DateTimeZone dateTimeZone = DateTimeZoneProviders.Bcl.GetZoneOrNull(BCLTimezoneID);

            //ZonedDateTime zonedDateTime = NodaLocalDateTimeUTC.InUtc().WithZone(dateTimeZone);

            OffsetDateTime offsetDateTime = new OffsetDateTime(NodaLocalDateTimeUTC, Offset.Zero);
            ZonedDateTime zonedDateTime = new ZonedDateTime(offsetDateTime.ToInstant(), dateTimeZone);
            return zonedDateTime.LocalDateTime;
        }
    }

    public OffsetDateTime NodaOffsetDateTime;

    public DateTime BclDateTimeUTC;
    public DateTime BclLocalDateTime
    {
        get
        {
            DateTime utcDateTime = DateTime.SpecifyKind(BclDateTimeUTC, DateTimeKind.Utc);
            TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(BCLTimezoneID);
            DateTime result = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
            return result;
        }
    }

    public DateTimeOffset BclDateTimeOffset;
    //public int Offset;
    public string OriginalDateString;
    public string BCLTimezoneID;
}

我确信 NodaTime 对象没有正确序列化,因为当我从 viewModel 注释代码时,JsonResult 能够执行。

我从这个页面上读到了这个NodaTime API Reference

此命名空间中的代码当前不包含在 Noda Time NuGet 包中;它仍然被认为是“实验性的”。要使用这些序列化程序,请从项目主页下载并构建 Noda Time 源代码。

所以我下载并构建了源代码并替换了我的项目引用的 dll,但我不知道如何实现 JsonSerialization 类。

有人可以向我解释如何使用 NodaTime.Serialization.JsonNet 类来使我的 NodaTime 对象可序列化吗?

【问题讨论】:

    标签: c# datetime nodatime


    【解决方案1】:

    我们目前不支持JavaScriptSerializer:我怀疑您必须使用Json.NET所有您的 JSON 序列化。 user guide page on serialization 提供了一点更多信息,但它主要假设您已经了解 Json.NET。

    好消息是 Json.NET 非常易于使用 - 您可能会发现它很简单:

    var settings = new JsonSerializerSettings();
    settings.ConfigureForNodaTime();
    string json = JsonConvert.SerializeObject(model, settings);
    

    (或使用JsonSerializer。)

    顺便说一句,您使用 Noda Time 类型的方式至少可以说有点奇怪 - 可能值得再问一个问题,详细说明您想要实现的目标,我们可以解决一种更惯用的方法:)

    【讨论】:

    • 我只是在制作一个示例项目,该项目将日期时间从客户端 -> 服务器 -> 数据库中保存并再次返回。所以我可以将 BCL 库与 NodaTime 进行比较?我的技术有什么奇怪的?如果是因为我使用属性,我只是希望它们是可序列化的。
    • @mac10688:这是您处理各种类型的方式 - 您正在经历很多转换,但我不清楚这些转换的目的是什么。您有一个名为NodaLocalDateTimeUTC 的字段这一事实令人担忧——因为LocalDateTime 在概念上不在任何时区。我很想帮助您理解所涉及的概念和类型 - 部分原因是它可能会引导我们编写更好的文档:)
    • 我明白你在说什么。是不是 LocalDateTime 没有“Kind”属性是有原因的,你认为我不应该强迫它?我这样做是因为我想将日期时间存储在 UTC 和 timezoneID 中,并且当我将它传递回客户端时,我可以利用这些信息构建本地化时间。在同一个示例中,我还存储了 datetimeoffset。因此,也许最好的解决方案是将 datetimeoffset 与 timezoneID 一起存储。在我的原型项目中,我最终想看看 nodatime 和 bcl 在并排比较中有何不同(即持久化 DateTimes 并对其进行操作)。
    • @mac10688:是的。您应该阅读 Noda Time 中的所有不同概念 - noda-time.googlecode.com/hg-history/1.0.x/docs/userguide/…noda-time.googlecode.com/hg-history/1.0.x/docs/userguide/…。听起来您实际上应该只存储一个ZonedDateTime,它可以存储为Instant(使用Ticks 属性来获取long 值)和一个时区ID。当然,如果更容易将其存储在数据库中,您可以转换为 DateTimeOffset(和时区 ID)。
    • @Thomas:请不要在 cmets 中提问。如果您确实需要,请提出新问题 - 但请先阅读相关文档。 (以nodatime.org/1.3.x/userguide/core-types.htmlnodatime.org/1.3.x/userguide/text.html 开头。)
    【解决方案2】:

    序列化是supported for JSON.NET in Noda Time 2.0+

    您需要使用 NuGet 安装该软件包:

    > Install-Package NodaTime.Serialization.JsonNet
    

    然后配置您的序列化程序设置以使用它。这不适用于默认的序列化器/反序列化器 - 您需要明确配置一个。

    我们选择静态使用一个。您的用法可能会有所不同。这是一个例子:

    using Newtonsoft.Json;
    using NodaTime;
    using NodaTime.Serialization.JsonNet; // << Needed for the extension method to appear!
    using System;
    
    namespace MyProject
    {
        public class MyClass
        {
            private static readonly JsonSerializerSettings _JsonSettings;
    
            static MyClass()
            {
                _JsonSettings = new JsonSerializerSettings
                {
                    // To be honest, I am not sure these are needed for NodaTime,
                    // but they are useful for `DateTime` objects in other cases.
                    // Be careful copy/pasting these.
                    DateFormatHandling = DateFormatHandling.IsoDateFormat,
                    DateTimeZoneHandling = DateTimeZoneHandling.Utc,
                };
    
                // Enable NodaTime serialization
                // See: https://nodatime.org/2.2.x/userguide/serialization
                _JsonSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
            }
    
            // The rest of your code...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多