Graph API中DriveItem Patch报错:需直接更新ListItem而非DriveItem
问题:如何通过Graph API更新DriveItem的自定义字段?
我正在使用ASP.NET Core开发一款通过Graph API访问文档库(List/Drive)的API,需要更新文档库中已创建的DriveItem,为其添加自定义列ID_Solicitacao,但调用Patch方法时收到无效请求错误。仅更新Name字段时可正常运行,请问如何更新自定义字段?
错误信息
{"message": "OData error occurred.", "details": "Cannot update a listItem via driveItem, patch the listItem directly"}
相关代码示例
public async Task<DriveItem?> CreateDriveItem(FileDTO file) { var fileBytes = Convert.FromBase64String(file.Base64); var fileNameWithExtension = file.FileName + file.FileType; var requestBody = new CreateUploadSessionPostRequestBody { Item = new DriveItemUploadableProperties { Name = fileNameWithExtension, } }; var uploadSession = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).CreateUploadSession.PostAsync(requestBody); if (uploadSession == null) { return null; } using var stream = new MemoryStream(fileBytes); await UploadFileInChunks(uploadSession.UploadUrl ?? "", stream); var createdItem = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Expand = new string[] { "listItem($expand=fields)" }; }); if (createdItem == null) { return null; } var requestBodyPatch = new DriveItem { Name = "NomeAtualizado com ID.txt", ListItem = new ListItem { Fields = new FieldValueSet { AdditionalData = new Dictionary<string, object> { {"ID_Solicitacao", 123 } } } } }; var patch = await _graphClient.Graph.Drives[_driveId].Items[createdItem.Id].PatchAsync(requestBodyPatch); if (patch == null) { return null; } return patch; }
解决方案:直接更新ListItem而非DriveItem
错误提示已经明确说明:不能通过DriveItem更新ListItem,必须直接对ListItem发起Patch请求。因此需要将更新操作拆分为两步:分别更新DriveItem的属性(如Name)和对应的ListItem自定义字段。
修改后的代码示例
public async Task<DriveItem?> CreateDriveItem(FileDTO file) { var fileBytes = Convert.FromBase64String(file.Base64); var fileNameWithExtension = file.FileName + file.FileType; var requestBody = new CreateUploadSessionPostRequestBody { Item = new DriveItemUploadableProperties { Name = fileNameWithExtension, } }; var uploadSession = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).CreateUploadSession.PostAsync(requestBody); if (uploadSession == null) { return null; } using var stream = new MemoryStream(fileBytes); await UploadFileInChunks(uploadSession.UploadUrl ?? "", stream); var createdItem = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Expand = new string[] { "listItem($expand=fields)" }; }); if (createdItem == null || createdItem.ListItem == null) { return null; } // 第一步:更新DriveItem的Name字段 var driveItemUpdate = new DriveItem { Name = "NomeAtualizado com ID.txt" }; await _graphClient.Graph.Drives[_driveId].Items[createdItem.Id].PatchAsync(driveItemUpdate); // 第二步:直接更新ListItem的自定义字段 var listItemUpdate = new ListItem { Fields = new FieldValueSet { AdditionalData = new Dictionary<string, object> { {"ID_Solicitacao", 123 } } } }; // 若不知道站点ID和列表ID,可先通过Drive获取关联List信息: // var driveList = await _graphClient.Graph.Drives[_driveId].List.GetAsync(); // 使用 driveList.ParentSiteId 作为站点ID,driveList.Id 作为列表ID await _graphClient.Graph.Sites["你的站点ID"].Lists["你的文档库列表ID"].Items[createdItem.ListItem.Id].PatchAsync(listItemUpdate); // 重新获取更新后的DriveItem(可选) var updatedItem = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath("NomeAtualizado com ID.txt").GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Expand = new string[] { "listItem($expand=fields)" }; }); return updatedItem; }
关键说明
- 拆分更新操作:DriveItem的属性(如Name)和ListItem的自定义字段需要分开更新,不能在同一个DriveItem的Patch请求中包含ListItem的修改。
- 获取站点和列表ID:如果不知道站点ID和文档库列表ID,可以通过
_graphClient.Graph.Drives[_driveId].List.GetAsync()获取关联的List信息,其中ParentSiteId是站点ID,Id是列表ID。 - 空值检查:操作前要确保
createdItem.ListItem不为null,避免空引用错误。
内容的提问来源于stack exchange,提问作者Bruno Bispo
相关产品推荐
相关产品推荐

