Microsoft Graph批量请求中CreateLink(POST)请求卡住问题解决
解决OneDrive批量请求中CreateLink POST请求卡住的问题
问题描述
批量请求始终在与POST请求CreateLink()相关的代码处卡住,不清楚如何在批量请求中正确处理POST请求,微软文档指出批量请求中的POST请求与GET请求处理方式不同。原代码如下:
public async Task<OneDriveFile> BulkFileImportAsync(string DriveID, string Path) { OneDriveFile oneDriveFile = new OneDriveFile(); try { var fileInfoRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .Request(); var fileEditRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .CreateLink("edit", "users", null, null, null, true) .Request(); var fileViewRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .CreateLink("view", "users", null, null, null, true) .Request(); var fileThumbnailRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path).Thumbnails .Request(); // Build the batch var batchRequestContent = new BatchRequestContent(); var fileInfoRequestId = batchRequestContent.AddBatchRequestStep(fileInfoRequest); var fileEditRequestId = batchRequestContent.AddBatchRequestStep(fileEditRequest); var fileViewRequestId = batchRequestContent.AddBatchRequestStep(fileViewRequest); var fileThumbnailRequestId = batchRequestContent.AddBatchRequestStep(fileThumbnailRequest); var returnedResponse = await _graphServiceClient.Batch.Request().PostAsync(batchRequestContent); var fileInfo = await returnedResponse .GetResponseByIdAsync<DriveItem>(fileInfoRequestId); var fileEdit = await returnedResponse .GetResponseByIdAsync<Permission>(fileEditRequestId); var fileView = await returnedResponse .GetResponseByIdAsync<Permission>(fileViewRequestId); var fileThumbnail = await returnedResponse .GetResponseByIdAsync<IDriveItemThumbnailsCollectionPage>(fileThumbnailRequestId); oneDriveFile.Path = Path; oneDriveFile.WebURL = fileInfo.WebUrl; oneDriveFile.EditURL = fileEdit.AdditionalData["webUrl"].ToString(); oneDriveFile.ViewURL = fileEdit.AdditionalData["webUrl"].ToString(); oneDriveFile.ThumbnailURL = fileThumbnail.CurrentPage[0].Large.Url; } catch (ServiceException ex) { Console.WriteLine($"Error doing batch update: {ex.ToString()}"); } return oneDriveFile; }
问题原因
Graph批量请求中,GET请求可直接通过AddBatchRequestStep传入请求对象,但POST请求(如CreateLink)需要携带请求体。直接传递IRequest对象时,批量请求框架可能未正确提取POST的请求体内容,导致请求卡住或失败。
解决方案
对于POST类型的请求,需先获取对应的HttpRequestMessage,再包装为BatchRequestStep添加到批量请求中。修改后的代码如下:
public async Task<OneDriveFile> BulkFileImportAsync(string DriveID, string Path) { OneDriveFile oneDriveFile = new OneDriveFile(); try { var fileInfoRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .Request(); var fileEditRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .CreateLink("edit", "users", null, null, null, true) .Request(); var fileViewRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path) .CreateLink("view", "users", null, null, null, true) .Request(); var fileThumbnailRequest = _graphServiceClient.Me.Drives[DriveID].Root .ItemWithPath(Path).Thumbnails .Request(); // Build the batch var batchRequestContent = new BatchRequestContent(); // GET请求直接添加 var fileInfoRequestId = batchRequestContent.AddBatchRequestStep(fileInfoRequest); var fileThumbnailRequestId = batchRequestContent.AddBatchRequestStep(fileThumbnailRequest); // POST请求需要先获取HttpRequestMessage,再添加到批量 var fileEditRequestMsg = await fileEditRequest.GetHttpRequestMessageAsync(); var fileEditRequestId = batchRequestContent.AddBatchRequestStep(new BatchRequestStep(fileEditRequestMsg)); var fileViewRequestMsg = await fileViewRequest.GetHttpRequestMessageAsync(); var fileViewRequestId = batchRequestContent.AddBatchRequestStep(new BatchRequestStep(fileViewRequestMsg)); var returnedResponse = await _graphServiceClient.Batch.Request().PostAsync(batchRequestContent); var fileInfo = await returnedResponse .GetResponseByIdAsync<DriveItem>(fileInfoRequestId); var fileEdit = await returnedResponse .GetResponseByIdAsync<Permission>(fileEditRequestId); var fileView = await returnedResponse .GetResponseByIdAsync<Permission>(fileViewRequestId); var fileThumbnail = await returnedResponse .GetResponseByIdAsync<IDriveItemThumbnailsCollectionPage>(fileThumbnailRequestId); oneDriveFile.Path = Path; oneDriveFile.WebURL = fileInfo.WebUrl; oneDriveFile.EditURL = fileEdit.AdditionalData["webUrl"].ToString(); // 修复原代码逻辑错误:使用fileView的webUrl赋值给ViewURL oneDriveFile.ViewURL = fileView.AdditionalData["webUrl"].ToString(); oneDriveFile.ThumbnailURL = fileThumbnail.CurrentPage[0].Large.Url; } catch (ServiceException ex) { Console.WriteLine($"Error doing batch update: {ex.ToString()}"); } return oneDriveFile; }
关键修改点
- POST请求处理:对
CreateLink生成的POST请求,调用GetHttpRequestMessageAsync()获取完整请求消息,再通过BatchRequestStep包装后添加到批量请求,确保请求体被正确携带。 - 修复逻辑bug:原代码中错误地将
fileEdit的webUrl同时赋值给EditURL和ViewURL,修改为使用fileView的对应值。
内容的提问来源于stack exchange,提问作者Qiuzman
相关产品推荐
相关产品推荐

