C#文件上传到SharePoint C#如何使用CSOM或Graph API上传文档

6次阅读

csom适用于.net framework环境且需app-only权限的后台上传,须注册app获取clientid/secret并用Tokenhelper认证;graph api适合.net core+msal场景,小文件≤4mb用put,大文件需createuploadsession分块上传。

C#文件上传到SharePoint C#如何使用CSOM或Graph API上传文档

CSOM上传文件到sharepoint文档库(.NET Framework 4.7.2+)

CSOM适合已部署在windows Server或传统.NET Framework环境、且有SharePoint Online管理员权限配置App-Only访问的场景。它不依赖用户登录态,适合后台服务调用。

关键点:必须先注册SharePoint App并获取ClientIdClientSecret,再用SharePointOnlineCredentials或更安全的ClientContext + TokenHelper方式认证。直接传用户名密码在现代身份验证下会失败。

  • 引用NuGet包:microsoft.SharePointOnline.CSOM(v16.1.23919.12000+)
  • 目标URL需是文档库根路径,例如:https://contoso.sharepoint.com/sites/team/Shared%20Documents
  • 上传前检查父文件夹是否存在,CSOM不会自动创建嵌套路径,context.Web.GetFolderByServerRelativeUrl()抛异常需自行捕获并递归创建
  • 大文件(>10MB)建议改用File.SaveBinaryDirect()或分块上传(StartUpload/ContinueUpload/FinishUpload),否则易超时
var ctx = new ClientContext("https://contoso.sharepoint.com/sites/team"); ctx.Credentials = new SharePointOnlineCredentials("user@contoso.com", securePassword); var fileCreationInfo = new FileCreationInformation {     Content = File.ReadAllBytes(@"C:tempreport.pdf"),     Url = "report.pdf",     Overwrite = true }; var docs = ctx.Web.Lists.GetByTitle("Shared Documents"); var uploadFile = docs.RootFolder.Files.Add(fileCreationInfo); ctx.Load(uploadFile); ctx.ExecuteQuery();

Graph API上传小文件(≤4MB)到SharePoint文档库

Graph API更适合.NET Core/.NET 5+项目,且已有azure AD应用注册(类型为“Web”)、已授Files.ReadWrite.AllSites.Write.All权限。它统一了onedrive和SharePoint的文件操作语义。

注意:Graph不直接暴露“文档库路径”,而是通过siteId + driveId定位——driveId对应文档库,需先用/sites/{site-id}/drives查出目标文档库的id,再调/drives/{drive-id}/root:/{filename}:/content上传。

  • 小文件(≤4MB)用PATCH /drives/{id}/items/{item-id}/content最简;无item-id时用PUT /drives/{id}/root:/{filename}:/content
  • 必须使用HttpClient带Bearer Token请求,Token需由Microsoft.Identity.Client(MSAL)获取,不能硬编码
  • 响应状态码201 Created表示成功,404大概率是driveId错或路径中文件夹不存在(Graph不自动建中间目录)
  • 中文文件名需URL编码,否则400 Bad Request
var url = $"https://graph.microsoft.com/v1.0/drives/{driveId}/root:/report.pdf:/content"; using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); var content = new ByteArrayContent(File.ReadAllBytes(@"C:tempreport.pdf")); content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); var resp = await client.PutAsync(url, content);

Graph分块上传大文件(>4MB)到SharePoint

超过4MB必须走createUploadSession流程,否则返回413 Payload Too Large。整个过程分三步:申请会话 → 分片上传 → 提交完成。会话有效期默认3小时,但每片上传后需更新过期时间。

容易漏掉的细节:每次PUT分片必须带Content-Range头,格式如bytes 0-1048575/5242880,且最后一片的range末尾值必须等于总大小减一;若某片失败,需重传该片,不能跳过。

  • 第一步:POST /drives/{id}/root:/{filename}:/createUploadSession,Body为空或含{"item": {"@microsoft.graph.conflictBehavior": "replace"}}
  • 第二步:对返回的uploadUrlPUT,Header加Content-RangeContent-Length,Body为当前分片字节
  • 第三步:最后一次PUT成功后,Graph自动返回完整driveItem对象,无需额外提交
  • .NET中推荐用Stream分段读取本地文件,避免File.ReadAllBytes()爆内存

CSOM vs Graph:选哪个?关键看这三点

没有绝对优劣,取决于你的运行环境、权限模型和文件大小分布。

  • 用CSOM:已有SharePoint App ID/Secret、服务长期运行、需上传>100MB文件(CSOM分块API更稳定)、或必须兼容SharePoint Server 2019(Graph不支持)
  • 用Graph:项目基于.NET Core、已用MSAL做统一认证、需同时操作OneDrive和SharePoint、或前端已调Graph(后端复用Token逻辑)
  • 混合用:常见于迁移场景——用Graph查元数据(快)、用CSOM传超大附件(稳)。但要注意两个API的权限粒度不同,Sites.FullControl.All不等价于CSOM的FullControl站点权限

最常被忽略的是权限同步延迟:Azure AD应用授权后,SharePoint端可能要等15分钟才生效,期间Graph返回403 Forbidden、CSOM报access denied,别急着改代码,先等一等。

text=ZqhQzanResources