我正在使用NewtonSoft的JsonConvert.DeserializeObject<AppraiserCalendarDto>(content)
方法,并尝试对以下内容进行反序列化,以查找资源在特定日期是否有效:
{
"2017-05-18": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-19": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-22": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-23": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-24": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-25": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"2017-05-26": {
"regular": {
"recordType": "working",
"workTimeStart": "08:00",
"workTimeEnd": "22:00"
}
},
"links": [
{
"rel": "canonical",
"href": "https://api.somedomain.com/rest/core/v1/resources/workSchedules/calendarView?dateFrom=2017-05-18&dateTo=2017-05-28"
},
{
"rel": "describedby",
"href": "https://api.somedomain.com/rest/core/v1/metadata-catalog/resources"
}
]
}
我要填充的模型类如下:
public class AppraiserCalendarDto
{
public Dictionary<DateTime, Record> Records { get; set; }
public class Record
{
[JsonProperty("recordType")]
public string RecordType { get; set; }
[JsonProperty("workTimeStart")]
public TimeSpan WorkTimeStart { get; set; }
[JsonProperty("workTimeEnd")]
public TimeSpan WorkTimeEnd { get; set; }
}
public List<Link> Links { get; set; }
public class Link
{
[JsonProperty("rel")]
public string Rel { get; set; }
[JsonProperty("href")]
public string Href { get; set; }
}
}
不幸的是,只有
List<Link> Links
被填充,而Records
字典为空。我尝试使用
Dictionary<string, Record>
而不是Dictionary<DateTime, Record>
获得相同的结果。任何反馈,不胜感激。
最佳答案
这里有两个问题导致了问题。首先,您打算进入字典的时间条目在JSON中与links
对象处于同一级别。反序列化器看不到它们,因为它期望它们位于JSON中名为records
的对象内,该对象与您的AppraiserCalendarDto
类中的dictionary属性的名称相对应。第二个问题是每次条目记录都位于JSON中名为regular
的对象内,但是在您的模型中没有相应的类。
一种可能的解决方案是,假设您可以控制JSON格式,则更改JSON以使其与模型匹配。但是,在大多数问题中,我都遇到这种类型的问题,这不是一个选择,因为JSON通常是在问询者控制范围之外的第三方API。如果是这样,那么另一个选择是实现自定义JsonConverter
来弥合差距。这是一个应该为您工作的转换器:
class AppraiserCalendarDtoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(AppraiserCalendarDto));
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
var dto = new AppraiserCalendarDto();
dto.Links = jo["links"].ToObject<List<AppraiserCalendarDto.Link>>();
var dict = new Dictionary<DateTime, AppraiserCalendarDto.Record>();
dto.Records = dict;
foreach (JProperty prop in jo.Properties().Where(p => p.Name != "links"))
{
var date = DateTime.Parse(prop.Name);
var record = prop.Value["regular"].ToObject<AppraiserCalendarDto.Record>();
dict.Add(date, record);
}
return dto;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用转换器,您可以使用
AppraiserCalendarDto
属性标记您的[JsonConverter]
类,如下所示:[JsonConverter(typeof(AppraiserCalendarDtoConverter))]
public class AppraiserCalendarDto
{
...
}
或者,您也可以像这样将实例传递给
JsonConvert.DeserializeObject<T>
:var dto = JsonConvert.DeserializeObject<AppraiserCalendarDto>(content,
new AppraiserCalendarDtoConverter());
演示小提琴:https://dotnetfiddle.net/yyErtO