【问题标题】:Upload very large file is tooo long上传非常大的文件太长
【发布时间】:2019-10-18 23:20:08
【问题描述】:

我有 ASP.NET Core WebApi 应用程序,需要上传非常大的文件。我已启用 JWT Auth/Authz

services.AddAuthentication(cfg =>
{
     cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
     cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, cfg =>
{ .. }

令牌的 TTL 为 2 分钟。

然后我在我的控制器中有动作

public async Task<IActionResult> Add(IFormFile file)
{
     if (file.Length.ToMegabytes() > 500)
     {
        throw new BadRequestException(nameof(file), "File size should not exceed 500 MB");
     }
}

在虚拟主机中配置

.UseKestrel(options =>
 {
    options.Limits.MaxRequestBodySize = null;
 })

当我上传一个大文件 (~1Gb) 时,它需要很长时间,然后在我采取行动之前返回 401。

如何在文件上传前检查该文件的大小无效?因为上传需要超过 2 分钟的时间,结果我会得到 401

【问题讨论】:

  • 这不是重复的,因为我问的是 abiut asp.net core webapi 但不是 asp.net 和 jquery
  • afaik,您无法在文件上传之前进行适当的检查,因为您需要上传文件才能让服务器知道文件有多大。
  • 但我的令牌将在所有检查之前过期。如何在不更改令牌生命周期的情况下处理它
  • 我认为主要思想在任何类型的框架或语言之间都没有改变,您应该尝试先在客户端进行检查

标签: c# asp.net-core asp.net-web-api


【解决方案1】:

问题在于,当对文件上传进行模型绑定时,必须将整个文件内容假脱机到服务器之前才能调用该操作。但是,特别是如果您要上传大文件,您不应该对上传进行模型绑定,而是将其流式传输。这也应该有解决您的授权问题的副作用,因为该操作将立即被调用。

docs 准确描述了如何流式传输大文件上传。这并非微不足道,但无论如何,为了获得最佳应用性能和稳定性,您都应该这样做。

【讨论】:

  • 谢谢,有道理。我可以使用流式传输,但在我的操作中保留参数 IFormFile file
  • 没有。如文档所示,您必须手动解析请求正文。这本质上就是模型绑定器正在做的事情,除非在这种情况下,它必须在 绑定IFormFile 参数之前完成文件的流式传输。这是因为在模型绑定器为该参数提供值之前,无法调用带有参数的操作。
  • 也就是说我不能再使用Swagger上传文件了,对吧?有什么方法可以使用 swagger 进行流式传输?
  • 这真的很有趣。我没有考虑过这种实际依赖方法的含义是自记录的,比如 Swagger。 理论上,如果您添加禁用模型绑定的属性,我想您可以保留该参数;它只是没有价值,所以从代码的角度来看会有点混乱。
  • 可能有一种方法可以欺骗 Swashbuckle/NSwag 来告诉它提供上传字段,而实际上没有参数。您必须检查相应的文档。
猜你喜欢
  • 2012-10-18
  • 2012-06-13
  • 1970-01-01
  • 2016-01-29
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 2018-10-27
相关资源
最近更新 更多