You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphAPI请求读写超时引发无效操作异常,SharePoint文件复制失败求助

问题解决:SharePoint复制PPT时MemoryStream超时异常处理

问题描述

我需要在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:41:26