C# Google Drive API上传文件 C#如何将文件上传到谷歌云盘

2次阅读

google drive api v3 认证必须用 oauth 2.0,服务账号不可行;本地开发应使用“桌面应用”凭据调用 authorizeasync 启动浏览器授权并缓存 Token.json,需启用 drive api、设对 redirect_uri 和作用域(如 drive.file)。

C# Google Drive API上传文件 C#如何将文件上传到谷歌云盘

google Drive API v3 的认证必须用 OAuth 2.0,服务账号行不通

Google Drive API 不允许服务账号(Service Account)直接写入普通用户网盘——哪怕你用 Subject 模拟用户,也必须确保该用户已显式授权服务账号访问其 https://www.googleapis.com/auth/drive.file 或更宽权限。本地开发最稳妥的方式是用 OAuth 2.0 用户凭据:调用 GoogleWebAuthorizationBroker.AuthorizeAsync 启动本地浏览器授权流程,首次运行会生成 token.json 缓存凭据。

容易踩的坑:

  • 忘记在 Google Cloud console 中为项目启用 Drive API(不止是创建凭据)
  • OAuth 凭据类型选成“服务账号密钥”或“API 密钥”,必须选“桌面应用”或“其他”
  • 未将 redirect_uri 设为 urn:ietf:wg:oauth:2.0:oobhttp://localhost(取决于客户端库版本)
  • 作用域写错,例如用了 drive.readonly 却想上传,应至少用 https://www.googleapis.com/auth/drive.file

上传文件需区分简单上传和分块上传

小文件(Files.Create + MediaUpload),大文件必须用分块上传(Files.Create with ResumableUpload)。C# 客户端库会自动选择,但你要主动控制 FileSizeSupportedUploadKinds 行为。

关键实操点:

  • 构造 Google.Apis.Drive.v3.Data.File 对象时,Parents 字段传 new List<string> { "folder_id" }</string> 才能指定目标文件夹;留空则上传到根目录
  • 设置 Body 后,必须调用 FilesResource.CreateRequest.UploadAsync()(不是 ExecuteAsync
  • 上传前检查 FileMetaData.MimeType,如不确定可调用 MimeMapping.GetMimeMapping("file.ext")(需引用 System.Web
  • 上传流必须是可重读的(stream.CanSeek == true),否则分块上传会失败;临时用 new MemoryStream(File.ReadAllBytes(path)) 最保险

上传后获取文件 ID 和分享链接要分两步

Files.Create 返回的 Google.Apis.Drive.v3.Data.File 对象只含基础字段(Id, Name, WebViewLink 等),但 WebViewLink 默认不可公开访问。若需外链,必须额外调用 Permissions.Create

常见错误场景:

  • 直接打印 file.WebViewLink,结果打开提示“您无权访问此内容”——因为权限未开放
  • 调用 Permissions.Create 时传了 type: "user" 却没填 emailAddress,应改用 type: "anyone" + role: "reader"
  • 误以为 file.Id 是短链接,实际它是长字符串 ID(如 1aBcDeFgHiJkLmNoPqRsTuVwXyZ),拼接 https://drive.google.com/file/d/{id}/view 才是标准链接

调试 403/404 错误优先查 scopes 和 folder ID 权限

上传失败时,GoogleApiException.Error.Code 为 403 多半是权限问题;404 则大概率是目标文件夹 ID 不存在或当前用户无访问权(哪怕文件夹是自己创建的,也要确认是否被移入“共享云端硬盘”且你有编辑权限)。

快速定位建议:

  • Files.List + Q = "'folder_id' in parents" 测试能否列出该文件夹下的内容
  • 捕获异常后打印 e.Error.Messagee.Error.Errors[0].Reason,常见值如 insufficientPermissionsnotFoundappNotAuthorized
  • 确认 OAuth token 缓存(token.json)未过期,且刷新逻辑已正确配置(GoogleWebAuthorizationBroker.AuthorizeAsync 内部会处理)
  • 如果上传到“共享云端硬盘”(Shared Drive),必须改用 supportsAllDrives = true 并用 corpora = "allDrives" 查询

真正麻烦的是权限继承和共享云端硬盘的混合场景——比如文件夹在共享云端硬盘里,但你的 OAuth 账号只是成员而非管理员,这时即使 ID 正确,上传也会静默失败或返回 404。这种 case 得先用 Drives.GetPermissions.List 交叉验证上下文权限,不能只盯着上传代码本身。

text=ZqhQzanResources