使用Microsoft Graph API批量创建日历休假事件遇无报错退出问题
问题:Microsoft Graph API批量创建日历休假请求无报错直接退出
我尝试通过Microsoft Graph API为用户日历批量创建休假请求,按照官方文档实现了批量请求,也试过HTTP请求方式,两种方式都出现无报错直接退出的情况。已经遵守了每批最多4个请求的限制。
调试时,程序仅执行到将每个事件转为POST请求的循环,在首次尝试添加批量请求步骤时停止,无任何报错。Graph Client在其他非批量操作中可正常工作。
批量创建事件的实现函数
public static async void PostTimeOffToCalendar(string upn, string udn, GraphServiceClient graphClient, List<DateTime> timesOff) { var calendarPosts = new List<Event>(); foreach (var date in timesOff) { Event requestBody = new() { Subject = $"Out of Office (PTO) - {udn}", Body = new ItemBody { ContentType = BodyType.Html, Content = "Scheduled time off." }, Start = new DateTimeTimeZone { DateTime = date.AddHours(8).ToString(), TimeZone = TimeZoneInfo.Local.StandardName }, End = new DateTimeTimeZone { DateTime = date.AddHours(17).ToString(), TimeZone = TimeZoneInfo.Local.StandardName }, IsOnlineMeeting = false, IsAllDay = false, ShowAs = FreeBusyStatus.Oof, IsReminderOn = true, ReminderMinutesBeforeStart = 30 }; calendarPosts.Add(requestBody); } foreach(var thing in calendarPosts) { Console.WriteLine(thing.Body.Content); } int maxNoBatchItems = 4; List<BatchRequestContent> batches = new(); BatchRequestContent batchRequestContent = new(graphClient); List<string> requestPostIds = new(); foreach (Event e in calendarPosts ) { var postEventRequest = graphClient.Users[upn].Events.ToPostRequestInformation(e); string requestPostId = await batchRequestContent.AddBatchRequestStepAsync(postEventRequest); requestPostIds.Add(requestPostId); if (calendarPosts.IndexOf(e) > 0 && ((calendarPosts.IndexOf(e) + 1) % maxNoBatchItems == 0)) { batches.Add(batchRequestContent); batchRequestContent = new BatchRequestContent(graphClient); } } if (batchRequestContent.BatchRequestSteps.Count < maxNoBatchItems) { batches.Add(batchRequestContent); } if (batches.Count == 0 && batchRequestContent != null) { batches.Add(batchRequestContent); } List<BatchResponseContent> batchResponses = new(); foreach (BatchRequestContent batch in batches) { batchResponses.Add(await graphClient.Batch.PostAsync(batch)); } foreach (var batchResponse in batchResponses) { foreach(var postID in requestPostIds) { var res = await batchResponse.GetResponseByIdAsync<Event>(postID); Console.WriteLine(res.Body + ";" + res.Id); } } }
Graph Client创建函数
public static GraphServiceClient CreateGraphClient(Settings settings) { string[] scopes = new[] { "https://graph.microsoft.com/.default" }; TokenCredentialOptions graphOptions = new() { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; ClientSecretCredential clientSecretCredential = new( settings.TenantId, settings.ClientId, settings.ClientSecret, graphOptions); GraphServiceClient graphClient; try { graphClient = new GraphServiceClient(clientSecretCredential, scopes); } catch { throw; // Re-throw the caught exception without additional handling } return graphClient ?? throw new Exception("Microsoft Graph Client not initialized correctly."); }
解决建议
- 修改异步方法返回类型:把
async void改为async Task,async void仅适用于事件处理场景,普通异步方法使用它会导致调用方无法等待执行完成,程序可能提前退出。调用该方法时需确保用await等待执行结束。 - 修复分批逻辑的索引问题:
calendarPosts.IndexOf(e)在列表存在重复对象时会返回错误索引,改用循环计数器跟踪当前位置:int index = 0; foreach (Event e in calendarPosts ) { var postEventRequest = graphClient.Users[upn].Events.ToPostRequestInformation(e); string requestPostId = await batchRequestContent.AddBatchRequestStepAsync(postEventRequest); requestPostIds.Add(requestPostId); index++; if (index > 0 && index % maxNoBatchItems == 0) { batches.Add(batchRequestContent); batchRequestContent = new BatchRequestContent(graphClient); } } - 添加异常捕获与日志:在异步方法中包裹try-catch块,输出异常信息以排查隐藏错误:
public static async Task PostTimeOffToCalendar(string upn, string udn, GraphServiceClient graphClient, List<DateTime> timesOff) { try { // 原方法逻辑 } catch (Exception ex) { Console.WriteLine($"错误信息: {ex.Message}\n调用栈: {ex.StackTrace}"); throw; } } - 规范日期格式:
date.AddHours(8).ToString()可能生成不符合Graph要求的格式,改用ISO 8601标准格式:date.AddHours(8).ToString("yyyy-MM-ddTHH:mm:ss") - 验证时区标识符:
TimeZoneInfo.Local.StandardName可能不是Graph认可的时区ID,建议使用TimeZoneInfo.Local.Id获取标准时区标识符,或直接指定如"China Standard Time"这类Graph兼容的时区名称。
内容的提问来源于stack exchange,提问作者isohel
相关产品推荐
相关产品推荐

