如何正确反序列化Microsoft Graph返回的ScheduleInformation JSON数据?
解决Microsoft Graph API ScheduleInformation集合反序列化问题
核心原因
Microsoft Graph SDK生成的ScheduleInformation等模型基于Kiota框架,包含自定义类型(如Microsoft.Kiota.Abstractions.Time、Microsoft.Graph.Models.FreeBusyStatus),普通JSON序列化库(Newtonsoft.Json/System.Text.Json)无法自动处理这些类型的转换,必须使用SDK自带的Kiota序列化器,或者手动添加类型转换器。
最优方案:使用SDK官方根对象+Kiota序列化器
- 官方根对象存在:API返回的ScheduleInformation集合对应的官方响应类型是
ScheduleInformationCollectionResponse,属于Microsoft.Graph.Models命名空间,无需自定义根对象。 - 用Kiota序列化器反序列化:
using Microsoft.Kiota.Serialization.Json; using Microsoft.Graph.Models; using System.IO; // 假设jsonString是API返回的原始JSON内容 var parseNodeFactory = new JsonParseNodeFactory(); using var jsonStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonString)); var rootParseNode = parseNodeFactory.GetRootParseNode("application/json", jsonStream); // 反序列化为官方响应对象 var scheduleResponse = rootParseNode.GetObjectValue<ScheduleInformationCollectionResponse>(); // 获取ScheduleInformation集合 var scheduleInfos = scheduleResponse.Value; - 关于GetFieldDeserializers:这个方法是Kiota框架内部用来处理自定义字段反序列化的逻辑,不需要手动调用,SDK的序列化器会自动调用这些方法完成类型转换。
备选方案:给普通序列化库添加类型转换器
如果必须使用Newtonsoft.Json或System.Text.Json,需为自定义类型编写转换器:
Newtonsoft.Json示例
- 编写
Time类型转换器:public class KiotaTimeConverter : JsonConverter<Microsoft.Kiota.Abstractions.Time> { public override Microsoft.Kiota.Abstractions.Time ReadJson(JsonReader reader, Type objectType, Microsoft.Kiota.Abstractions.Time existingValue, bool hasExistingValue, JsonSerializer serializer) { var timeString = reader.Value?.ToString(); return string.IsNullOrEmpty(timeString) ? default : Microsoft.Kiota.Abstractions.Time.FromTimeSpan(TimeSpan.Parse(timeString)); } public override void WriteJson(JsonWriter writer, Microsoft.Kiota.Abstractions.Time value, JsonSerializer serializer) { writer.WriteValue(value?.ToTimeSpan().ToString(@"hh\:mm\:ss")); } } - 编写
FreeBusyStatus枚举转换器:public class FreeBusyStatusConverter : JsonConverter<Microsoft.Graph.Models.FreeBusyStatus> { public override Microsoft.Graph.Models.FreeBusyStatus ReadJson(JsonReader reader, Type objectType, Microsoft.Graph.Models.FreeBusyStatus existingValue, bool hasExistingValue, JsonSerializer serializer) { var statusString = reader.Value?.ToString(); return string.IsNullOrEmpty(statusString) ? default : Enum.Parse<Microsoft.Graph.Models.FreeBusyStatus>(statusString, ignoreCase: true); } public override void WriteJson(JsonWriter writer, Microsoft.Graph.Models.FreeBusyStatus value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } } - 注册转换器并反序列化:
var jsonSettings = new JsonSerializerSettings(); jsonSettings.Converters.Add(new KiotaTimeConverter()); jsonSettings.Converters.Add(new FreeBusyStatusConverter()); var rootObject = JsonConvert.DeserializeObject<YourCustomRootObject>(jsonString, jsonSettings);
System.Text.Json示例
类似地,编写JsonConverter子类并注册到JsonSerializerOptions中,逻辑和Newtonsoft.Json一致,这里不再赘述。
注意:手动编写转换器的方式需要维护与SDK模型的兼容性,后续SDK更新可能需要同步修改转换器,因此优先推荐使用Kiota自带的序列化器方案。
内容的提问来源于stack exchange,提问作者David Shochet
相关产品推荐
相关产品推荐

