文件上传中间件,支持分片断点上传,目前还在开发迭代中,可能有些地方会做调整,目前不建议使用到生成环境
Packages | NuGet |
---|---|
UploadMiddleware.Core | |
UploadMiddleware.LocalStorage | |
UploadMiddleware.AliyunOSS |
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddUploadLocalStorage(options =>
{
options.RootDirectory = Configuration.GetSection("SaveRootDirectory").Value;
options.AddAllowFileExtension(".mp4");
options.AddUploadCompletedHandler<CustomUploadCompletedHandler>();
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddChunkedUploadLocalStorage(options =>
{
options.AddAllowFileExtension(".zip",".mp4");
options.RootDirectory = Configuration.GetSection("SaveRootDirectory").Value;
options.DeleteChunksOnMerged = true;
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddUploadAliyunOSS(options =>
{
options.AccessId = Configuration.GetSection("OSS:AccessId").Value;
options.AccessKeySecret = Configuration.GetSection("OSS:AccessKeySecret").Value;
options.BucketName = Configuration.GetSection("OSS:BucketName").Value;
options.Endpoint = Configuration.GetSection("OSS:Endpoint").Value;
options.RootDirectory = Configuration.GetSection("OSS:RootDirectory").Value;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//配置上传路由
app.UseUpload("/upload");
}
上传文件路由
路由 | 请求类型 | ContentType |
---|---|---|
/upload | POST | multipart/form-data |
请求参数 | 类型 | 位置 | 说明 |
---|---|---|---|
file | binary | body | 至少要上传一个文件 |
file-md5 | string | header | 文件的MD5值,分片上传时必须 |
chunk | int | header | 当前上的分片索引,从0开始,分片上传时必须 |
检查已经上传的分片数量
路由 | 请求类型 | ContentType | 说明 |
---|---|---|---|
/upload?action=chunks | POST | application/x-www-form-urlencoded | 此接口只适用于单线程,分片按顺序上传 |
请求参数 | 类型 | 位置 | 说明 |
---|---|---|---|
file-md5 | string | header | 文件的MD5值 |
返回值 | 类型 | 说明 |
---|---|---|
errmsg | string | 具体的错误信息 |
chunks | int | 已经上传的分片数量,默认会是已经上传的分片数量减一,因为可能最后一个分片不完整 |
检查单个分片的完整性
路由 | 请求类型 | ContentType |
---|---|---|
/upload?action=chunk | POST | application/x-www-form-urlencoded |
请求参数 | 类型 | 位置 | 说明 |
---|---|---|---|
chunk-md5 | string | header | 分片的MD5值 |
file-md5 | string | header | 文件的MD5值 |
chunk | int | header | 分片索引,从0开始 |
返回值 | 类型 | 说明 |
---|---|---|
errmsg | string | 具体的错误信息 |
data | int | 0或1,1表示分片完整 |
合并分片
路由 | 请求类型 | ContentType |
---|---|---|
/upload?action=merge | POST | application/x-www-form-urlencoded |
请求参数 | 类型 | 位置 | 说明 |
---|---|---|---|
file-md5 | string | header | 文件的MD5值 |
chunks | int | header | 分片数量 |
参数 | 类型 | 说明 |
---|---|---|
RootDirectory | string | 文件保存的根目录 |
MultipartBodyLengthLimit | long | Multipart Body的上限,Kestrel服务下才起作用,IIS下请在web.config里配置 |
AllowFileExtension | HashSet | 允许上传的文件格式(以"."开头),默认有:.jpg,.jpeg,.png,.gif,可以自行添加和删除 |
BufferSize | int | 缓冲池大小(默认64KB),推荐不要超过64KB,超过后会写磁盘 |
ChunksRootDirectory | string | 存放分片的跟目录,不设置则默认使用RootDirectory |
DeleteChunksOnMerged | bool | 当分片合并完成时,是否删除分片,(默认:True) |
AccessId | string | OSS access key Id |
AccessKeySecret | string | OSS key secret |
Endpoint | string | OSS endpoint |
BucketName | string | OSS bucket name |
SecurityToken | string | STS security token |
Metadata | Dictionary | 设置文件的元数据,每种文件格式可以单独配置,可使用以下占位符:$(form:name): 表单数据,name是具体的form表单key;$(query:name): query参数,name是具体的query参数key;$LocalFileName: 本地文件名;$SectionName: MultipartBody的name值; |
AddUploadCompletedHandler | method | 添加自定义(文件/分片)上传完成返回结果组装Handler |
AddUploadProcessor | method | 添加自定义上传处理器 |
AddFileValidator | method | 添加自定义文件格式验证器 |
AddSubdirectoryGenerator | method | 添加子目录生成器 |
AddFileNameGenerator | method | 添加文件名生成器 |
AddCheckChunksProcessor | method | 添加自定义分片数量检测器 |
AddCheckChunkProcessor | method | 添加自定义分片完整性检测器 |
AddMergeProcessor | method | 添加自定义分片合并器 |
AddMergeHandler | method | 添加分片合并完成返回结果组装Handler |
- 分片上传会有两种情况,一种是前端多线程上传,一种是单线程上传。
- 如果是多线程上传,上传分片的顺序可能是乱的,所以如果你需要支持断点续传的话,需要在上传前检查分片的完整性。
- 单线程上传的话就简单一些,只要前端保证按顺序上传就可以,如果需要支持断点续传,只需要在上传前检查已经上传的分片数量,默认情况下返回的分片数量会是已经上传的分片数量减一,因为最后一个分片可能是不完整的,当然你也可以选择没个分片都验证完整性。
- 前端推荐使用WebUploader
- 很多人上传文件只是单纯的验证文件的后缀名,这是不安全的。
- UploadMiddleware默认的文件验证器,不止验证了后缀名,还会根据后缀名验证文件的签名,具体的文件签名可以去这两个地方查询:https://www.filesignatures.net/index.php?page=search , https://en.wikipedia.org/wiki/List_of_file_signatures
- UploadMiddleware内置了常用(.jpg、.png、.gif、.bmp、.mp3、.mp4、.rar、.zip、.doc、.docx、.xls、.xlsx、.ppt、.pptx、.pdf)的文件签名,可通过FileSignature类查询和添加
- UploadMiddleware是中间件,中间件内不能加权限过滤器。
- 解决办法是在项目里写一个跟中间件路由一致的空api,api不需要有任何逻辑,也不会被调用,并加上AuthorizeAttribtue即可解决授权问题。