GraphAPI请求读写超时引发无效操作异常,SharePoint文件复制失败求助
问题描述
我需要在SharePoint中创建新文件夹,随后复制一份PPT到该文件夹。我发起了两个请求:一个用于获取文件本身,另一个获取文件内容以完成复制。但执行以下代码时:
var tester = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath("FolderPath/Template.pptx").Content.Request().GetAsync();
无法成功完成文件复制,调试时发现System.IO.MemoryStream类型的tester抛出了与Read.Timeout和Write.Timeout相关的无效操作异常。
现有创建文件夹的代码如下:
public async Task<string> Sharepoint_FolderCreate(string NewFolderName, string sharepoint_folder_path = "/SomeFolderPath") { var item = new DriveItem { Name = NewFolderName.Replace("?", " ").Replace("/", " ").Replace("\\", " ").Replace("<", " ").Replace(">", " ").Replace("*", " ").Replace("\"", " ").Replace(":", " ").Replace("|", " "), Folder = new Folder { }, AdditionalData = new Dictionary<string, object>() { {"@microsoft.graph.conflictBehavior","rename"} } }; var scopes = new[] { "https://graph.microsoft.com/.default" }; var options = new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var clientSecretCredential = new ClientSecretCredential( tenantID, clientId, clientSecret, options); var graphClient = new GraphServiceClient(clientSecretCredential, scopes); var sharepoint = await graphClient.Sites.GetByPath("/sites/SiteFolder", "localhost.sharepoint.com").Request().GetAsync(); await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath(sharepoint_folder_path).Children.Request().AddAsync(item); var NewFolder = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath($"{sharepoint_folder_path}/{item.Name}").Request().GetAsync(); return NewFolder.WebUrl; }
解决方案
1. 理解MemoryStream的特性
MemoryStream本身不支持超时设置,直接访问Read.Timeout或Write.Timeout属性会触发InvalidOperationException,这是类的设计特性,无需尝试修改这些属性。
2. 使用Graph API原生复制操作(推荐)
不需要手动下载再上传文件,直接调用Graph API的Copy方法更高效,还能避免流操作的问题:
// 获取源文件的DriveItem对象 var sourceFile = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath("FolderPath/Template.pptx").Request().GetAsync(); // 构建复制请求体 var copyRequest = new ItemCopyPostRequestBody { ParentReference = new ItemReference { Id = NewFolder.Id }, // 指定目标文件夹ID Name = "Copied_Template.pptx" // 复制后的文件名 }; // 执行复制 await graphClient.Sites[sharepoint.Id].Drive.Items[sourceFile.Id].Copy.PostAsync(copyRequest);
3. 优化手动流操作(若必须使用)
如果一定要手动处理文件流,确保正确管理流的生命周期,不要访问Timeout属性:
using (var fileStream = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath("FolderPath/Template.pptx").Content.Request().GetAsync()) { // 直接将流上传到目标文件夹 await graphClient.Sites[sharepoint.Id].Drive.Items[NewFolder.Id].ItemWithPath("Copied_Template.pptx").Content.Request().PutAsync(fileStream); }
4. 基础检查
- 确认应用已配置
Files.ReadWrite.All或Sites.ReadWrite.All权限 - 验证源文件路径、目标文件夹路径的拼写是否正确
- 确保新文件夹创建完成后再执行复制操作(现有代码中已通过
GetAsync获取新文件夹,此步骤已覆盖)
内容的提问来源于stack exchange,提问作者freyfrey01
相关产品推荐
相关产品推荐

