Graph API读取日历事件Expand Extensions时JSON解析错误求助
问题:Graph API读取带Open Extensions的日历事件时JSON解析失败
我用C#和Graph API为委派用户创建、读取日历事件,不使用Open Extensions时一切正常。创建带OpenTypeExtension的日历事件代码可成功执行,但读取时取消注释requestConfiguration.QueryParameters.Expand = new string[] { "extensions" };后,无法读取任何事件,抛出JSON解析错误。
创建带OpenTypeExtension的事件代码
var precomExtension = new OpenTypeExtension { OdataType = "microsoft.graph.openTypeExtension", ExtensionName = "com.zxcasd.zxcasdExtensions", AdditionalData = new Dictionary<string, object> { { "zxcasd" , "1234586" } } }; var @event = new Event { Subject = "Kalle Anka", Body = new ItemBody { ContentType = BodyType.Text, Content = "This is a test from zxczxc, sorry for any inconvinience it may cause" }, Start = new DateTimeTimeZone { DateTime = "2025-12-24T14:00:00", TimeZone = "Pacific Standard Time" }, End = new DateTimeTimeZone { DateTime = "2025-12-24T15:00:00", TimeZone = "Pacific Standard Time" }, Location = new Location { DisplayName = "Conference Room" }, Extensions = new List<Extension> { precomExtension }, }; try { await graphClient.Users[userEmail].Events.PostAsync(@event); Console.WriteLine("Event created successfully!"); } catch (ServiceException ex) { Console.WriteLine($"Error creating event: {ex.Message}"); }
读取事件代码(取消注释Expand后报错)
var events3 = await graphServiceClient .Users[user] .Events .GetAsync(requestConfiguration => { requestConfiguration.QueryParameters.Select = new string[] { "Id", "Subject", "Start", "End", "Organizer", "createdDateTime", "lastModifiedDateTime" }; requestConfiguration.QueryParameters.Expand = new string[] { "extensions" }; requestConfiguration.QueryParameters.Filter = $"start/dateTime ge '{startDateString}' and end/dateTime le '{endDateString}'"; requestConfiguration.QueryParameters.Orderby = new string[] { $"start/dateTime" }; requestConfiguration.QueryParameters.Top = 9999; }); if (events3?.Value?.Count() > 0) { Console.WriteLine($"Nr of retrived events: {events3.Value.Count}"); Console.WriteLine("*********************************"); } foreach (var eventItem in events3.Value) { Console.WriteLine($"Id: {eventItem.Id}"); Console.WriteLine($"Start: {eventItem.Start.DateTime}"); Console.WriteLine($"End: {eventItem.End.DateTime}"); Console.WriteLine($"Subject: {eventItem.Subject}"); Console.WriteLine($"Organizer: {eventItem.Organizer?.EmailAddress?.Name ?? "No organizer"}"); Console.WriteLine($"Created: {eventItem.CreatedDateTime}"); Console.WriteLine($"LastModified: {eventItem.LastModifiedDateTime}"); Console.WriteLine("*********************************"); }
抛出的错误信息
{"Expected depth to be zero at the end of the JSON payload. There is an open JSON object or array that should be closed. LineNumber: 0 | BytePositionInLine: 437."} BytePositionInLine: 437 Data: {System.Collections.ListDictionaryInternal} HResult: -2146233088 HelpLink: null InnerException: null LineNumber: 0 Message: "Expected depth to be zero at the end of the JSON payload. There is an open JSON object or array that should be closed. LineNumber: 0 | BytePositionInLine: 437." Path: null Source: "System.Text.Json" StackTrace: " at System.Text.Json.Utf8JsonReader.ReadSingleSegment()\r\n at System.Text.Json.Utf8JsonReader.Read()\r\n at System.Text.Json.JsonDocument.Parse(ReadOnlySpan`1 utf8JsonSpan, JsonReaderOptions readerOptions, MetadataDb& database, StackRowStack& stack)\r\n at System.Text.Json.JsonDocument.Parse(ReadOnlyMemory`1 utf8Json, JsonReaderOptions readerOptions, Byte[] extraRentedArrayPoolBytes, PooledByteBufferWriter extraPooledByteBufferWriter)\r\n at System.Text.Json.JsonDocument.<ParseAsyncCore>d__65.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory.<GetRootParseNodeAsync>d__7.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Abstractions.Serialization.ParseNodeProxyFactory.<GetRootParseNodeAsync>d__8.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Abstractions.Serialization.ParseNodeFactoryRegistry.<GetRootParseNodeAsync>d__9.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Abstractions.Serialization.ParseNodeProxyFactory.<GetRootParseNodeAsync>d__8.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<GetRootParseNodeAsync>d__30.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<SendAsync>d__20`1.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<SendAsync>d__20`1.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Graph.Users.Item.Events.EventsRequestBuilder.<GetAsync>d__8.MoveNext()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at AzureCalendar.Program.<GetCalendarAppointments>d__5.MoveNext() in E:\_Code_\Testing\AzureCalendar\AzureCalendar\Program.cs:line 229" TargetSite: {Boolean ReadSingleSegment()}
问题原因
这个错误的核心是批量扩展所有extensions时,Graph API返回的扩展类型混合(包含系统扩展和自定义扩展),导致Kiota序列化器无法正确解析JSON结构。另外,部分事件没有扩展时,返回的extensions字段为null或空数组,和带有扩展的事件返回结构不一致,进一步加剧了解析冲突。
解决方案
1. 过滤扩展,只获取自定义的OpenTypeExtension
不要直接扩展所有extensions,而是通过$filter指定自定义扩展的ID,这样只会返回目标扩展,避免系统扩展干扰:
requestConfiguration.QueryParameters.Expand = new string[] { "extensions($filter=id eq 'com.zxcasd.zxcasdExtensions')" };
2. 单独获取每个事件的扩展
先读取所有事件,再针对每个事件单独请求扩展,规避批量解析的类型冲突:
foreach (var eventItem in events3.Value) { Console.WriteLine($"Id: {eventItem.Id}"); Console.WriteLine($"Start: {eventItem.Start.DateTime}"); // 其他属性输出... // 单独获取当前事件的扩展 var extensions = await graphServiceClient.Users[user].Events[eventItem.Id].Extensions.GetAsync(); if (extensions?.Value?.Count > 0) { var customExt = extensions.Value.FirstOrDefault(e => e.Id == "com.zxcasd.zxcasdExtensions") as OpenTypeExtension; if (customExt != null) { Console.WriteLine($"Custom zxcasd value: {customExt.AdditionalData["zxcasd"]}"); } } Console.WriteLine("*********************************"); }
3. 升级Graph SDK版本
如果使用的是较旧的Graph SDK v5版本,可能存在Kiota序列化器的bug,升级到最新稳定版可以解决部分解析异常问题。
内容的提问来源于stack exchange,提问作者merger
相关产品推荐
相关产品推荐

