我正在使用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

10-05 19:15