反序列化NodaTime LocalDate时出现异常

时间:2017-07-10 18:28:49

标签: c# json serialization nodatime

在反序列化包含JSON序列化LocalDate对象的JSON字符串时,我看到一个异常(请参阅此问题的结尾以获取JSON代码段。)

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

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

我看到了这条异常消息:

  

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

这是MyObject类:

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

以下是我尝试反序列化的JSON代码段:

{
    "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"
}

2 个答案:

答案 0 :(得分:3)

我现在已经弄明白了 - 我的问题是我在ASP.NET路由处理程序中的错误假设。 @ L.B&#39的问题实际上让我思考了一点。

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

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

此API的结果与问题中的JSON代码段相同。

为每个API处理程序调用{​​{1}}并传递SerializeObject并不是一个好主意,因为我在每个路由处理程序上丢失了对象返回类型。

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

ConfigureServices

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

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

这是DeserializeObject也期望的格式。

答案 1 :(得分:-1)

你可以使用像这样的类结构

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; }
}