反序列化 NodaTime LocalDate 时出现异常
Exception when deserializing NodaTime LocalDate
我在反序列化包含 JSON 序列化 LocalDate 对象的 JSON 字符串时看到异常(请参阅此问题的结尾以获取 JSON 片段)。
这就是我反序列化的方式:
var settings = new JsonSerializerSettings();
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var output = JsonConvert.DeserializeObject<MyObject>(json, settings);
我看到这条异常信息:
NodaTime.Utility.InvalidNodaDataException: 'Unexpected token parsing LocalDate. Expected String, got StartObject.'
这是 MyObject class:
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"
}
我现在想通了 - 我的问题是我在 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 片段相同。
为每个 API 处理程序调用 SerializeObject
并传递 settings
也不是一个好主意,因为我在每个路由处理程序上丢失了对象 return 类型我有。
为了确保 LocalDate
在 每个 处理程序中正确序列化,我在 Startup
的 ConfigureServices
方法中执行以下操作 class:
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 也期望的格式。
你可以使用这样的class结构
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; }
}
我在反序列化包含 JSON 序列化 LocalDate 对象的 JSON 字符串时看到异常(请参阅此问题的结尾以获取 JSON 片段)。
这就是我反序列化的方式:
var settings = new JsonSerializerSettings();
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var output = JsonConvert.DeserializeObject<MyObject>(json, settings);
我看到这条异常信息:
NodaTime.Utility.InvalidNodaDataException: 'Unexpected token parsing LocalDate. Expected String, got StartObject.'
这是 MyObject class:
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"
}
我现在想通了 - 我的问题是我在 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 片段相同。
为每个 API 处理程序调用 SerializeObject
并传递 settings
也不是一个好主意,因为我在每个路由处理程序上丢失了对象 return 类型我有。
为了确保 LocalDate
在 每个 处理程序中正确序列化,我在 Startup
的 ConfigureServices
方法中执行以下操作 class:
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 也期望的格式。
你可以使用这样的class结构
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; }
}