OssClient 初始化必须传 endpoint、AccessKeyId、AccessKeySecret 三参数且顺序固定;endpoint须为纯域名;AK/SK禁硬编码;bucket需手动创建并匹配地域;RAM账号需授予oss:PutObject权限;GetObject返回流须显式释放。
用 OssClient 初始化时 AK 必须带 SecretKey,不能只传 AccessKeyId
很多人卡在第一步:构造 ossclient 报错 invalidaccesskeyid 或直接 403,其实不是权限没开,而是初始化参数写错了。阿里云 oss .net sdk 要求必须同时提供 accesskeyid、accesskeysecret 和 endpoint,缺一不可,且顺序不能颠倒。
-
OssClient构造函数签名是OssClient(string endpoint, string accessKeyId, string accessKeySecret),不是“可选参数”或“配置对象”,别想省略 Secret - endpoint 不能写成
https://oss-cn-hangzhou.aliyuncs.com这种带协议的完整 URL,得是纯域名形式:oss-cn-hangzhou.aliyuncs.com - AK/SK 绝对不能硬编码在代码里,尤其别提交到 Git —— 推荐从
Configuration["OSS:AccessKeyId"]或环境变量读取
上传文件前先确认 PutObject 的 bucketName 已存在且有写权限
调用 PutObject 报错 NoSuchBucket 或 AccessDenied,大概率不是代码问题,而是 bucket 状态不对。OSS 不会自动创建 bucket,也不会在上传时帮你兜底。
- 控制台手动创建 bucket 后,检查“地域”是否和代码中 endpoint 一致(比如 endpoint 是
oss-cn-shanghai.aliyuncs.com,bucket 就必须建在华东2) - RAM 子账号若用于上传,需明确授予
oss:PutObject权限,仅给oss:GetObject是不够的 - 如果用的是自定义域名(如
cdn.example.com),PutObject仍必须指向原始 OSS endpoint,不能传自定义域名
GetObject 返回流要手动释放,不关 Stream 会导致连接池耗尽
常见现象:跑一段时间后请求变慢、超时增多,查日志发现 System.Net.Http.HttpRequestException: Connection refused —— 很可能是忘了释放 GetObjectResult.ResponseStream。
-
GetObject返回的GetObjectResult包含一个未关闭的Stream,必须显式调用.Dispose()或用using包裹 - 别直接返回这个 Stream 给 ASP.NET Core 的
FileStreamResult,它不会自动 dispose;应该先 copy 到内存或新 stream 再释放原 stream - 小文件(GetObjectResult.Content 直接拿
byte[],避免流管理风险
删除多个 object 用 DeleteObjects,别循环调 DeleteObject
批量删 100 个文件,如果写 for 循环每次调一次 DeleteObject,不仅慢(100 次 HTTP 请求),还容易触发 OSS 的 QPS 限流(默认 1000 QPS / bucket)。
-
DeleteObjects一次最多删 1000 个 object,传入IEnumerable<string></string>的 key 列表即可 - 注意返回的
DeleteObjectsResult中DeletedObjects是成功列表,DeleteErrors才是失败项,别只看 StatusCode 判断整体成败 - 如果 key 数量超 1000,自己分批,别指望 SDK 自动拆分
C# 调 OSS 最容易出问题的地方不在语法,而在 endpoint、bucket 生命周期、AK 权限粒度这些外部依赖状态 —— 写完代码先去控制台核对一遍 bucket 和 RAM 策略,比反复改代码快得多。










