【翻译】Tusdotnet中文文档(1)配置和用法
TUSDOTNET
Tusdotnet是tus协议的一个dotnet实现。tus协议是用来规范文件上传的整个过程,tus基于http协议,规定了一些上传过程中的头部(headers)和对上传过程的描述。它实现了文件的断点恢复上传以及其他的一些实用的规范。我前面文章中,有关于tus的详细文档。在对tusdotnet文档的翻译过程中,我删除了关于IIS的章节,因为IIS的章节单独放在一章中,所以删除IIS对于其他章节没有任何影响。因为我本人从来不会将.net core的项目部署到IIS上。
Tusdotnet的官方文档在这里:https://github.com/tusdotnet/tusdotnet/wiki
本章按照如下目录进行翻译:
配置
- 总体配置
- 跨域请求处理
用法
- 创建文件之前检查文件的元数据
- 文件上传完成后的处理
- 下载文件
- 删除过期的未完成文件
总体配置
tusdotnet使用下面的方式很容易配置:
app.UseTus(context => new DefaultTusConfiguration {... });
上述代码中提供的工厂(context => new ...
)会作用于每一个请求上。通过检查传入的HttpContext/IOwinRequest,可以为不同的客户机返回不同的配置。
工厂返回的是一个单利的DefaultTusConfiguration实例,这个实例包含如下属性:
public class DefaultTusConfiguration
{
/// <summary>
/// 用于监听上传的URL路径 (比如 "/files").
///如果站点位于子路径中(例如https://example.org/mysite),也必须包含它(例如/mysite/files)。
/// </summary>
public virtual string UrlPath { get; set; } /// <summary>
/// The store to use when storing files.
/// </summary>
public virtual ITusStore Store { get; set; } /// <summary>
/// Callbacks to run during different stages of the tusdotnet pipeline.
/// </summary>
public virtual Events Events { get; set; } /// <summary>
/// The maximum upload size to allow. Exceeding this limit will return a "413 Request Entity Too Large" error to the client.
/// Set to null to allow any size. The size might still be restricted by the web server or operating system.
/// This property will be preceded by <see cref="MaxAllowedUploadSizeInBytesLong" />.
/// </summary>
public virtual int? MaxAllowedUploadSizeInBytes { get; set; } /// <summary>
/// The maximum upload size to allow. Exceeding this limit will return a "413 Request Entity Too Large" error to the client.
/// Set to null to allow any size. The size might still be restricted by the web server or operating system.
/// This property will take precedence over <see cref="MaxAllowedUploadSizeInBytes" />.
/// </summary>
public virtual long? MaxAllowedUploadSizeInBytesLong { get; set; } /// <summary>
/// Set an expiration time where incomplete files can no longer be updated.
/// This value can either be <code>AbsoluteExpiration</code> or <code>SlidingExpiration</code>.
/// Absolute expiration will be saved per file when the file is created.
/// Sliding expiration will be saved per file when the file is created and updated on each time the file is updated.
/// Setting this property to null will disable file expiration.
/// </summary>
public virtual ExpirationBase Expiration { get; set; }
}
根据所使用的存储类型,可能还需要对存储进行一些配置。tusdotnet附带的磁盘存储需要一个目录路径,以及是否应该在连接(指concatenation扩展)时删除“部分(指Upload-Concat:partial)”文件。
Store = new TusDiskStore(@"C:\tusfiles\", deletePartialFilesOnConcat: true)
在上面的例子中,C:\tusfiles\是保存所有文件的地方,deletePartialFilesOnConcat: true表示,一旦创建了最终文件(Upload-Concat:final),就应该删除部分文件(仅由连接扩展(concatenation extension)使用)。默认值为false,因此不会意外删除任何文件。如果不确定,或者没有使用连接扩展,则将其设置为false。有关详细信息,请参见Custom data store -> ITusConcatenationStore.
跨域请求处理
为了能够让浏览器通过不同域来上传文件,你需要个体tusdotnet配置跨域请求的相关设置。
关于跨域的配置非常简单:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors(builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.WithExposedHeaders(tusdotnet.Helpers.CorsHelper.GetExposedHeaders())
);
app.UseTus(...);
}
在创建文件之前检查文件的元数据
OnBeforeCreate事件用来在创建文件之前检查文件的元数据
OnBeforeCreate事件在创建文件之前触发。
在传递给回调函数的BeforeCreateContext上调用FailRequest将使用400错误码来拒绝请求。多次调用FailRequest将串联/连接错误消息。
app.UseTus(context => new DefaultTusConfiguration
{
UrlPath = "/files",
Store = new TusDiskStore(@"C:\tusfiles\"),
Events = new Events
{
OnBeforeCreateAsync = ctx =>
{
if (!ctx.Metadata.ContainsKey("name"))
{
ctx.FailRequest("name metadata must be specified. ");
} if (!ctx.Metadata.ContainsKey("contentType"))
{
ctx.FailRequest("contentType metadata must be specified. ");
} return Task.CompletedTask;
}
});
文件上传完成后的处理
OnFileCompleteAsync事件用于文件上传完成后的处理
该事件会在文件上传完成后触发。
app.UseTus(request => new DefaultTusConfiguration
{
Store = new TusDiskStore(@"C:\tusfiles\"),
UrlPath = "/files",
Events = new Events
{
OnFileCompleteAsync = async ctx =>
{
// ctx.FileId is the id of the file that was uploaded.
// ctx.Store is the data store that was used (in this case an instance of the TusDiskStore) // A normal use case here would be to read the file and do some processing on it.
var file = await ((ITusReadableStore)ctx.Store).GetFileAsync(ctx.FileId, ctx.CancellationToken);
var result = await DoSomeProcessing(file, ctx.CancellationToken); if (!result.Success)
{
throw new MyProcessingException("Something went wrong during processing");
}
}
}
});
下载文件
由于tus规范不包含下载文件tusdotnet将自动将所有GET请求转发给下一个中间件,因此开发人员可以选择允许文件下载。
下面的示例要求数据存储实现ITusReadableStore (TusDiskStore实现了)。如果没有,就必须找出文件的存储位置,并以其他方式读取它们。
app.Use(async (context, next) =>
{
// /files/ is where we store files
if (context.Request.Uri.LocalPath.StartsWith("/files/", StringComparison.Ordinal))
{
// Try to get a file id e.g. /files/<fileId>
var fileId = context.Request.Uri.LocalPath.Replace("/files/", "").Trim();
if (!string.IsNullOrEmpty(fileId))
{
var store = new TusDiskStore(@"C:\tusfiles\");
var file = await store.GetFileAsync(fileId, context.Request.CallCancelled); if (file == null)
{
context.Response.StatusCode = ;
await context.Response.WriteAsync($"File with id {fileId} was not found.", context.Request.CallCancelled);
return;
} var fileStream = await file.GetContentAsync(context.Request.CallCancelled);
var metadata = await file.GetMetadataAsync(context.Request.CallCancelled); // The tus protocol does not specify any required metadata.
// "contentType" is metadata that is specific to this domain and is not required.
context.Response.ContentType = metadata.ContainsKey("contentType")
? metadata["contentType"].GetString(Encoding.UTF8)
: "application/octet-stream"; if (metadata.ContainsKey("name"))
{
var name = metadata["name"].GetString(Encoding.UTF8);
context.Response.Headers.Add("Content-Disposition", new[] { $"attachment; filename=\"{name}\"" });
} await fileStream.CopyToAsync(context.Response.Body, , context.Request.CallCancelled);
return;
}
}
删除过期的未完成的文件
如果正在使用的存储支持ITusExpirationStore (TusDiskStore支持),则可以指定未在指定时间段内更新的不完整文件应该标记为过期。如果在ITusConfiguration上设置了过期属性(Expiration-Property),并且存储支持ITusExpirationStore,则tusdotnet将自动执行此操作。但是文件不会自动删除。为了帮助删除过期的不完整文件,ITusExpirationStore接口公开了两个方法,GetExpiredFilesAsync和DeleteExpiredFilesAsync。前者用于获取已过期文件的id列表,后者用于删除过期文件。
如上所述,tusdotnet不会自动删除过期的文件,所以这需要开发人员来实现。建议在web应用程序添加合适的端点(EndPoint)来运行你自己的代码。这些代码是用诸如crontab之类的工具(比如HangFire)来轮询(或者其他的方式)删除过期未完成上传的文件。
示例程序:
IEnumerable<string> expiredFileIds = await tusDiskStore.GetExpiredFilesAsync(cancellationToken);
// Do something with expiredFileIds.
int numberOfRemovedFiles = await tusDiskStore.RemoveExpiredFilesAsync(cancellationToken);
// Do something with numberOfRemovedFiles.
本篇完。
【翻译】Tusdotnet中文文档(1)配置和用法的更多相关文章
- 【翻译】Tusdotnet中文文档(2)事件
tusdotnet-----一个tus文件上传协议的实现之事件 本章接上篇来继续翻译Tusdotnet的文档,按照如下结构来翻译: 事件 OnAuthorize OnFileComplete OnBe ...
- 【翻译】Tusdotnet中文文档(3)自定义功能和相关技术
自定义功能和相关技术 本篇按照如下结构翻译 自定义功能 自定义数据仓库 相关技术 架构和总体概念 自定义数据仓库 tusdotnet附带一个存储库TusDiskStore,它将文件保存在磁盘上的一个目 ...
- [转]Magento 2中文文档教程 - 配置和运行cron(定时任务)
本文转自:https://blog.csdn.net/xz_src/article/details/72793476 cron(定时任务)概述 Magento 2 有许多功能需要用到cron(定时任务 ...
- ORCHARD中文文档(翻译)
众所周知,Orchard是.net领域最好的开源CMS之一,他使用了微软最先进的技术,有一群先进理念的支持者,但是,所有的事情在国内总得加个但是,Orchard也不例外,中文资料相对比较少,官网提供的 ...
- Keras官方中文文档:Keras安装和配置指南(Windows)
这里需要说明一下,笔者不建议在Windows环境下进行深度学习的研究,一方面是因为Windows所对应的框架搭建的依赖过多,社区设定不完全:另一方面,Linux系统下对显卡支持.内存释放以及存储空间调 ...
- Phoenix综述(史上最全Phoenix中文文档)
个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...
- Spring中文文档
前一段时间翻译了Jetty的一部分文档,感觉对阅读英文没有大的提高(*^-^*),毕竟Jetty的受众面还是比较小的,而且翻译过程中发现Jetty的文档写的不是很好,所以呢翻译的兴趣慢慢就不大了,只能 ...
- PHP开发框架Laravel优点,Laravel5.3中文文档
PHP开发框架Laravel优点 Laravel的设计思想是很先进的,非常适合应用各种开发模式TDD, DDD和BDD,作为一个框架,它为你准备好了一切,composer是个php的未来,没有comp ...
- Core 中文文档
ASP.NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序 原文:Your First ASP. ...
随机推荐
- 05showLoading配置和 <text>标签的坑 如何发送请求 分享功能和懒加载
14-电影-列表-需求分析 小程序里面取数据 没有冒号这么一说 加载动画 在对应页面 js文件中 showLoading你可以去看他的配置 // wx.showLoading() 应用在让用户 ...
- 201871010104-陈园园 《面向对象程序设计(java)》第十二周学习总结
201871010104-陈园园 <面向对象程序设计(java)>第十二周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- day15_7.17正则表达式与re模块
一.正则表达式 在用户登录注册,以及身份验证时,会发现,如果在手机号的窗口输入字母等不是手机号的格式的字符串时,会报错,这种筛选字符串的功能就是由正则表达式提供. 正则表达式是几乎所有编程语言都会设计 ...
- djang小项目过程中的小问题 02(跳转界面)
我觉着自己生下来就是解决问题的 ##1. 今天在使用登录注册模板时,输入后缀index,正常显示登录界面,但是点击 立即注册 之后不会跳转到注册页面 因为我观察到后缀名发生变化了,但是出发点是错的,前 ...
- NOIP 2009 Hankson 的趣味题
洛谷 P1072 Hankson 的趣味题 洛谷传送门 JDOJ 1648: [NOIP2009]Hankson的趣味题 T2 JDOJ传送门 Description Hanks 博士是BT (Bio ...
- HttpRuntime应用程序运行时
System.Web.HttpRuntime类是整个Asp.net服务器处理的入口. 这个类提供了一系列的静态属性,反映web应用程序域的设置信息,而且每个web应用程序域中存在一个System.We ...
- elasticsearch 简单demo RestHighLevelClient LowLeveClient
参考: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.7/java-rest-low.html www.elasti ...
- Gym101002E:K-Inversions
\(Gym101002E:K-Inversions\) 题意描述: 题目连接链接 给定一个长度为\(N\)只包含\(AB\)的字符串,某个\(A\)的位置为\(j\),某个\(B\)的位置为\(i\) ...
- calc()在less中编译报错
calc()对大家来说,或许很陌生,不太会相信calc()是css中的部分.因为看其外表像个函数,既然是函数为何又出现在CSS中呢? calc() 函数用于动态计算长度值. 需要注意的是,运算符前后都 ...
- [LeetCode] 252. Meeting Rooms 会议室
Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...