Azure Function用Graph SDK上传SharePoint附件报错:需可读取可查找流
解决Graph SDK 5.36.0大文件上传"Must provide stream that can read and seek"错误(Azure Function环境)
问题根源
LargeFileUploadTask要求传入的流必须支持Seek操作,但通过_graphClient.Drives[...].Content.GetAsync()返回的流通常是不可seek的网络流;同时Azure Function无本地磁盘权限,无法使用FileStream作为替代。
解决方案
将下载的不可seek流复制到内存中的可seek MemoryStream,再用于上传任务,具体步骤如下:
- 将下载流转换为可seek的MemoryStream
// 从SharePoint下载文件流 Stream downloadStream = await _graphClient.Drives[drive.Id].Items[driveItem.Id].Content.GetAsync(); // 复制到可seek的MemoryStream var seekableStream = new MemoryStream(); await downloadStream.CopyToAsync(seekableStream); // 重置流指针到起始位置,确保上传时从开头读取 seekableStream.Position = 0;
- 修正上传任务的泛型类型
邮件附件的大文件上传任务泛型应使用AttachmentItem而非DriveItem(DriveItem适用于OneDrive/SharePoint文件上传,而非邮件附件):
var fileUploadTask = new LargeFileUploadTask<AttachmentItem>(uploadSession, seekableStream, maxSliceSize);
- 确保上传会话请求体配置正确
创建上传会话时,需用转换后的流长度设置附件大小:
var requestBody = new CreateAttachmentSessionPostRequestBody { AttachmentItem = new AttachmentItem { AttachmentType = AttachmentType.File, Name = driveItem.Name, Size = seekableStream.Length // 使用可seek流的长度 } }; var uploadSession = await _graphClient.Users[sender].Messages[draft.Id].Attachments.CreateUploadSession.PostAsync(requestBody);
说明
- 新创建的MemoryStream完全在内存中操作,无需本地磁盘,适配Azure Serverless环境。
- 分片上传时,LargeFileUploadTask需要多次移动流指针,可seek的流才能满足这一需求。
内容的提问来源于stack exchange,提问作者Ofer Gal
相关产品推荐
相关产品推荐

