【问题标题】:Exception when deserializing NodaTime LocalDate反序列化 NodaTime LocalDate 时出现异常
【发布时间】:2017-07-10 18:28:49
【问题描述】:

我在反序列化包含 JSON 序列化 LocalDate 对象的 JSON 字符串时看到异常(请参阅本问题的结尾以了解 JSON sn-p)。

这就是我反序列化的方式:

var settings = new JsonSerializerSettings();
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var output = JsonConvert.DeserializeObject<MyObject>(json, settings);

我看到这条异常消息:

NodaTime.Utility.InvalidNodaDataException: '意外的令牌解析 LocalDate。预期的字符串,得到了 StartObject。'

这是 MyObject 类:

class MyObject
{
    public LocalDate Date { get; set; }
    public string AnotherProperty { get; set; }
}

这是我试图反序列化的 JSON sn-p:

{
    "Date": {
        "Calendar": {
            "Id": "ISO",
            "Name": "ISO",
            "MinYear": -9998,
            "MaxYear": 9999,
            "Eras": [{
                "Name": "BCE"
            }, {
                "Name": "CE"
            }]
        },
        "Year": 2017,
        "Month": 7,
        "Day": 10,
        "DayOfWeek": 1,
        "YearOfEra": 2017,
        "Era": {
            "Name": "CE"
        },
        "DayOfYear": 191
    },
    "AnotherProperty": "A string"
}

【问题讨论】:

  • 我已经用 MyObject 的定义更新了问题
  • 只需创建一个简单的 LocalDate 类并对其进行序列化。现在将结果与您提供的 json 进行比较。 NodaTime.LocalDate d = new NodaTime.LocalDate(); var json = JsonConvert.SerializeObject(d, Newtonsoft.Json.Formatting.Indented);
  • @L.B - 我在反序列化过程中遇到了这个问题,而不是序列化
  • 我知道。我读了你的问题。我要说的是:您得到的 json 与您发布的不同。那么你希望如何正确地反序列化它。
  • 进一步了解您的意思,我意识到设置对象(因为它在问题中)也需要传递到 SerializeObject。这是因为 .NET 的内置 Json 转换器对 LocalDate 的序列化与 DeserializeObject 的预期不同。

标签: c# json serialization nodatime


【解决方案1】:

我现在已经弄清楚了——我的问题是我在 ASP.NET 路由处理程序中的一个错误假设。 @L.B 的问题实际上让我想多了。

我假设内置 JSON 序列化程序在此示例中正确序列化 MyObject 中的 LocalDate:

[HttpGet("myobject")]
public MyObject GetMyObject()
{
    return new MyObject()
    {
        Date = LocalDate.FromDateTime(DateTime.Now),
        AnotherProperty = "A string"
    };
}

此 API 的结果将与问题中的 JSON sn-p 相同。

为每个 API 处理程序调用 SerializeObject 并传入 settings 也不是一个好主意,因为我丢失了我拥有的每个路由处理程序的对象返回类型。

为了确保LocalDate每个 处理程序中正确序列化,我在Startup 类的ConfigureServices 方法中执行以下操作:

services.AddMvc().AddJsonOptions(options =>
{
    // NodaConverters lives in the NodaTime.Serialization.JsonNet assembly
    options.SerializerSettings.Converters.Add(NodaConverters.LocalDateConverter);
});

现在,当我调用上述 API 时,LocalDate 已正确序列化,如下所示:

{
    "Date":"2017-07-10",
    "AnotherProperty":"A string"
}

这也是 DeserializeObject 所期望的格式。

【讨论】:

  • 是的,您需要使用 Noda Time 的一组 JsonConverter 对象来获得正确的序列化和反序列化。这是in the user guide
【解决方案2】:

你可以像这样使用类结构

public class Era
{
    public string Name { get; set; }
}

public class Calendar
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int MinYear { get; set; }
    public int MaxYear { get; set; }
    public List<Era> Eras { get; set; }
}

public class Era2
{
    public string Name { get; set; }
}

public class Date
{
    public Calendar Calendar { get; set; }
    public int Year { get; set; }
    public int Month { get; set; }
    public int Day { get; set; }
    public int DayOfWeek { get; set; }
    public int YearOfEra { get; set; }
    public Era2 Era { get; set; }
    public int DayOfYear { get; set; }
}

public class RootObject
{
    public Date Date { get; set; }
    public string AnotherProperty { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    相关资源
    最近更新 更多