# OnceMi.AspNetCore.OSS
**Repository Path**: MiKeNetProject/oncemi_aspnetcore_oss
## Basic Information
- **Project Name**: OnceMi.AspNetCore.OSS
- **Description**: Asp.Net Core OSS对象储存服务,支持Minio,阿里云OSS,腾讯云OSS。
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: main
- **Homepage**: https://github.com/oncemi/OnceMi.AspNetCore.OSS
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 14
- **Created**: 2022-03-02
- **Last Updated**: 2022-03-02
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# OnceMi.AspNetCore.OSS
Asp.Net Core对象储存扩展包,支持Minio自建对象储存、阿里云OSS、腾讯云COS、七牛云Kodo、华为云OBS。支持OSS常规操作,比如储存桶创建,删除、对象上传、下载、生成签名URL等。目前支持.NET Core3.1/.NET 5/.NET 6,推荐升级至.NET 6.
## 各厂家相关SDK文档
- Minio: [点此查看](https://docs.min.io/docs/dotnet-client-api-reference.html "点此查看")
- Aliyun: [点此查看](https://help.aliyun.com/document_detail/32085.html "点此查看")
- QCloud: [点此查看](https://cloud.tencent.com/document/product/436/32819 "点此查看")
- 七牛云: [点此查看](https://developer.qiniu.com/kodo/1237/csharp "点此查看")
- HuaweiOBS:[点此查看](https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_0001.html "点此查看")
## 已知问题
1. Minio通过Nginx发反向代理后直接通过域名(不加端口)调用存在问题,应该是Minio本身问题,有兴趣的可以自行测试研究,具体信息我已经发布在Issue中。
2. 腾讯云`PutObjectAsync`流式上传接口,有非常低的概率会抛“储存桶不存在的异常”,应该是腾讯云自身的原因,具体原因未知。
## 如何使用
1、安装`OnceMi.AspNetCore.OSS`依赖。
Cmd install:
```shell
dotnet add package OnceMi.AspNetCore.OSS
```
Nuget: [](https://www.nuget.org/packages/OnceMi.AspNetCore.OSS)
2、在`Startup.cs`中配置
You need to configure OSSService in your Startup.cs:
```csharp
//default minio
//添加默认对象储存配置信息
services.AddOSSService(option =>
{
option.Provider = OSSProvider.Minio;
option.Endpoint = "oss.oncemi.com:9000";
option.AccessKey = "Q*************9";
option.SecretKey = "A**************************Q";
option.IsEnableHttps = true;
option.IsEnableCache = true;
});
//aliyun oss
//添加名称为‘aliyunoss’的OSS对象储存配置信息
services.AddOSSService("aliyunoss", option =>
{
option.Provider = OSSProvider.Aliyun;
option.Endpoint = "oss-cn-hangzhou.aliyuncs.com";
option.AccessKey = "L*******************U";
option.SecretKey = "5*******************************T";
option.IsEnableCache = true;
});
//qcloud oss
//也可以从配置文件中加载节点为‘OSSProvider’的配置信息
services.AddOSSService("QCloud", "OSSProvider");
```
可注入多个OSSService,不同的Service用名称来区分。需要注意的是,腾讯云COS中配置节点Endpoint表示AppId。
appsettings.json配置文件实例:
```csharp
{
"OSSProvider": {
"Provider": "QCloud", //枚举值支持:Minio/Aliyun/QCloud
"Endpoint": "你的AppId", //腾讯云中表示AppId
"Region": "ap-chengdu", //地域
"AccessKey": "A****************************z",
"SecretKey": "g6I***************la",
"IsEnableCache": true //是否启用缓存,推荐开启
}
}
```
3、使用Demo
```csharp
///
/// 使用默认的配置文件
///
public class HomeController : Controller
{
private readonly ILogger _logger;
private readonly IOSSService _OSSService;
private readonly string _bucketName = "default-dev";
public HomeController(ILogger logger
, IOSSService OSSService)
{
_logger = logger;
_OSSService = OSSService;
}
}
```
```csharp
///
/// 获取IOSSServiceFactory,根据名称创建对应的OSS服务
///
public class QCloudController : Controller
{
private readonly ILogger _logger;
private readonly IOSSService _OSSService;
private readonly string _bucketName = "default-dev";
public QCloudController(ILogger logger
, IOSSServiceFactory ossServiceFactory)
{
_logger = logger;
_OSSService = ossServiceFactory.Create("QCloud");
}
}
```
列出bucket中的全部文件
```csharp
public async Task ListBuckets()
{
try
{
var result = await _OSSService.ListBucketsAsync();
return Json(result);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
```
### 配置参数
| 名称 | 类型 | 说明 | 案例 | 备注 |
| :------------ |:------------ | :------------ | :------------ | :------------ |
| Provider | 枚举 | OSS提供者 | Minio | 允许值:Minio,Aliyun, QCloud |
| Endpoint | string | 节点 | oss-cn-hangzhou.aliyuncs.com | 在腾讯云OSS中表示AppId |
| AccessKey | string | AccessKey | F...............s | |
| SecretKey | string | SecretKey | v...............d | |
| Region | string | 地域 | ap-chengdu | |
| SessionToken | string | token | | 仅Minio中使用 |
| IsEnableHttps | bool | 是否启用HTTPS | true | 建议启用 |
| IsEnableCache | bool | 是否启用缓存 | true | 启用后将缓存签名URL,以减少请求次数 |
### API参考
##### BucketExistsAsync
`Task BucketExistsAsync(string bucketName);`
判断该储存桶是否存在。
##### CreateBucketAsync
`Task CreateBucketAsync(string bucketName);`
创建一个储存桶。如果当前储存桶存在,将抛出异常`BucketExistException`。
##### ListBucketsAsync
`Task ListBucketsAsync();`
列出当前账号下允许访问的所有储存桶。
##### RemoveBucketAsync
`Task RemoveBucketAsync(string bucketName);`
移除当前储存桶。移除储存桶之前,请先移除储存桶中所有的对象和对象碎片文件。
##### SetBucketAclAsync
`Task SetBucketAclAsync(string bucketName, AccessMode mode);`
设置储存桶的外部访问权限,支持的权限有:私有、公共读、公共读写。返回设置结果(True or False)。
##### GetBucketAclAsync
`Task GetBucketAclAsync(string bucketName);`
获取储存桶的外部访问权限。
##### ObjectsExistsAsync
`Task ObjectsExistsAsync(string bucketName, string objectName);`
获取指定储存桶中指定对象是否存在。
##### ListObjectsAsync
`Task> ListObjectsAsync(string bucketName, string prefix = null);`
列出当前储存桶所有文件。如果储存桶中文件较多,可以需要较长的执行时间,因此推荐填写prefix参数,prefix会根据文件名称进行前端匹配。比如输出abc,则列出全部abc开头的文件或目录。
##### GetObjectAsync
获取文件的数据流。
Methos 1:
`Task GetObjectAsync(string bucketName, string objectName, Action callback, CancellationToken cancellationToken = default);`
Example
```csharp
try
{
await _OSSService.GetObjectAsync(_bucketName, "1.jpg", (stream) =>
{
using (FileStream fs = new FileStream("1.jpg", FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fs);
fs.Close();
}
});
return Json("OK");
}
catch (Exception ex)
{
throw ex;
}
```
Methos 2:
`Task GetObjectAsync(string bucketName, string objectName, string fileName, CancellationToken cancellationToken = default);`
Example
```csharp
try
{
await _OSSService.GetObjectAsync(_bucketName, "1.jpg", "C:\\Temp\\1.jpg");
return Json("OK");
}
catch (Exception ex)
{
throw ex;
}
```
##### PutObjectAsync
上传文件。支持流式上传和上传本地文件。腾讯云不止流式上传,为了兼容接口,采用先将流加载到内存中再上传。
Method 1(流式上传):
`Task PutObjectAsync(string bucketName, string objectName, Stream data, CancellationToken cancellationToken = default(CancellationToken));`
Example
```csharp
try
{
byte[] bs = System.IO.File.ReadAllBytes(@"C:\Users\sysru\Desktop\PHOTO-1.jpg");
using (MemoryStream filestream = new MemoryStream(bs))
{
await _OSSService.PutObjectAsync(_bucketName, "PHOTO-1.jpg", filestream);
}
return Json("OK");
}
catch (Exception ex)
{
throw;
}
```
Method 2(上传本地文件):
`Task PutObjectAsync(string bucketName, string objectName, string filePath, CancellationToken cancellationToken = default);`
Example
```csharp
try
{
await _OSSService.PutObjectAsync(_bucketName, "PHOTO-1.jpg", @"C:\Users\sysru\Desktop\PHOTO-1.jpg");
return Json("OK");
}
catch (Exception ex)
{
throw;
}
```
##### GetObjectMetadataAsync
```csharp
Task GetObjectMetadataAsync(string bucketName
, string objectName
, string versionID = null
, string matchEtag = null
, DateTime? modifiedSince = null);
```
获取对象的元数据,或根据VersionId获取对象元数据。需要注意的是,在阿里云对象存储和腾讯云对象存储中不支持matchEtag和modifiedSincecan参数。
##### CopyObjectAsync
`Task CopyObjectAsync(string bucketName, string objectName, string destBucketName, string destObjectName = null);`
在储存桶之间复制对象。
##### RemoveObjectAsync
`Task RemoveObjectAsync(string bucketName, string objectName);`
删除储存桶中指定对象。
`Task RemoveObjectAsync(string bucketName, List objectNames);`
删除储存桶中多个对象。
##### RemovePresignedUrlCache
`void RemovePresignedUrlCache(string bucketName, string objectName);`
清除对象生成的签名URL缓存。在未开启签名URL缓存的情况下,此功能无效。
##### PresignedGetObjectAsync
`Task PresignedGetObjectAsync(string bucketName, string objectName, int expiresInt);`
生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,且不能超过7天。
如果该对象拥有公共读权限或该对象继承了储存桶的公共读权限,将生成永久下载链接。
如果Option参数中设置为IsEnableCache为True,将会在有效时间中缓存生成的签名链接,同时也推荐开启此功能,将大大降低请求的频率。
##### PresignedPutObjectAsync
`Task PresignedPutObjectAsync(string bucketName, string objectName, int expiresInt);`
生成一个给HTTP PUT请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行上传,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,且不能超过7天。
如果Option参数中设置为IsEnableCache为True,将会在有效时间中缓存生成的签名链接,同时也推荐开启此功能,将大大降低请求的频率。
注意:七牛云对象储存不支持此操作!
##### SetObjectAclAsync
`Task SetObjectAclAsync(string bucketName, string objectName, AccessMode mode);`
设置对象的访问权限,默认文件的访问权限是继承储存桶的。但是可以单独通过此API为对象设置访问权限。
注意:七牛云对象储存不支持此操作!
##### GetObjectAclAsync
`Task GetObjectAclAsync(string bucketName, string objectName);`
获取对象的储存桶权限,如果是该权限继承自储存桶,获取的可能是储存桶对当前对象的访问权限。
注意:七牛云对象储存不支持此操作!
##### RemoveObjectAclAsync
`Task RemoveObjectAclAsync(string bucketName, string objectName);`
清除该对象的访问权限或将其恢复至继承权限。
注意:七牛云对象储存不支持此操作!
## Dependencies
1. Aliyun.OSS.SDK.NetCore
2. Microsoft.Extensions.Caching.Memory
3. Newtonsoft.Json
4. Tencent.QCloud.Cos.Sdk
## To do list
1. 修改签名URL过期策略为滑动过期策略
2. 文件分页加载