重庆熊猫 Loading

ASP.NET Core教程-Configuration(配置)-文件上传

更新记录
转载请注明出处:
2022年11月16日 发布。
2022年11月12日 从笔记迁移到博客。

文件上传基础

文件上传安全措施(Security considerations)

  • 将文件上传到专用文件上传区域,最好是非系统驱动器。 使用专用位置便于对上传的文件实施安全限制。 禁用对文件上传位置的执行权限。
  • 请勿将上传的文件保存在与应用相同的目录树中。
  • 使用应用确定的安全的文件名。 请勿使用用户提供的文件名或上传的文件的不受信任的文件名。† 当显示不受信任的文件名时 HTML 会对它进行编码。 例如,记录文件名或在 UI 中显示(Razor 自动对输出进行 HTML 编码)。
  • 按照应用的设计规范,仅允许已批准的文件扩展名。
  • 验证是否对服务器执行客户端检查。客户端检查易于规避。
  • 检查已上传文件的大小。 设置一个大小上限以防止上传大型文件。
  • 文件不应该被具有相同名称的上传文件覆盖时,先在数据库或物理存储上检查文件名,然后再上传文件。
  • 先对上传的内容运行病毒/恶意软件扫描程序,然后再存储文件。

文件上传方式(File upload scenarios)

使用文件缓冲(Buffering

The entire file is read into an IFormFile, which is a C# representation of the file used to process or save the file.

文件上传所用的资源(磁盘、内存)取决于并发文件上传的数量和大小。 如果应用尝试缓冲过多上传,站点就会在内存或磁盘空间不足时崩溃。 如果上传的文件太大或上传频率过快,请使用流式传输。

注意:不建议使用。

流式处理(Streaming

The individual files uploaded to the server can be accessed through Model Binding using IFormFile.When uploading files using model binding and IFormFile.

IFormFile 接口定义

public interface IFormFile
{
    string ContentType { get; }			    //上传文件的原始Content-Type标头
    string ContentDisposition { get; }		//上传文件的原始Content-Disposition标头
    IHeaderDictionary Headers { get; }		//上传文件的HTTP Header集合
    long Length { get; }				   //上传文件长度,以字节为单位
    string Name { get; }				   //从Content-Disposition标头中获取表单字段名称
    string FileName { get; }
    Stream OpenReadStream();
    void CopyTo(Stream target);
    Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
}

如果是多个文件,可以使用集合即可:

IFormFileCollection
IEnumerable<IFormFile>
List<IFormFile>

具体实现:

public async Task<IActionResult> OnPostUploadAsync(List<IFormFile> files)
{
    //遍历获得文件
    foreach (var formFile in files)
    {
        //检测文件的大小大于0
        if (formFile.Length > 0)
        {
            //创建文件存储路径
            var fileSavePath = Path.Combine(_config["StoredFilesPath"], Path.GetRandomFileName());
		   //创建文件流
            using (var stream = System.IO.File.Create(fileSavePath))
            {
                //保存文件
                await formFile.CopyToAsync(stream);
            }
        }
    }

    //获得文件的大小(不是必须)
	long size = files.Sum(f => f.Length);
    //返回响应
    return Ok(new { count = files.Count, size });
}

还可以验证文件后缀类型是否符合要求

private string[] permittedExtensions = { ".txt", ".pdf" };

var ext = Path.GetExtension(uploadedFileName).ToLowerInvariant();

if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
{
    // The extension is invalid ... discontinue processing the file
}

文件上传正文大小限制

文件通过HTTP协议进行传输,受到Body大小限制。可以在服务中进行设置。

全局HTTP Body大小设置

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<FormOptions>(options =>
    {
        // Set the limit to 256 MB
        options.MultipartBodyLengthLimit = 268435456;
    });
}

Kestrel 最大请求正文大小限制

对于 Kestrel 托管的应用,默认的最大请求正文大小为 30,000,000 个字节,约为 28.6 MB。 使用 MaxRequestBodySize 服务器选项自定义此限制:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel((context, options) =>
            {
                // Handle requests up to 50 MB
                options.Limits.MaxRequestBodySize = 52428800;
            })
            .UseStartup<Startup>();
        });

IIS请求大小限制

默认的请求限制 (maxAllowedContentLength) 为 30,000,000 个字节,约为 28.6 MB。 在 web.config 文件中自定义此限制。 在下面的示例中,此限制设置为 50 MB(52,428,800 个字节):

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="52428800" />
    </requestFiltering>
  </security>
</system.webServer>

注意事项

HTML编码设置

enctype记得设置为multipart/form-data

 <form method="post" enctype="multipart/form-data" asp-controller="UpLoadFile" asp-action="FileSave">

name记得对应到后端的参数,如果允许多个文件,记得带上multiple参数

<input type="file" name="files" multiple />

后端参数特性修饰

如果无法接收到文件,可以试试加上[FromForm]特性。

  public async Task<ApiResult> UpFile([FromForm]IFormCollection formcollection)
posted @ 2022-11-16 09:13  重庆熊猫  阅读(283)  评论(0编辑  收藏  举报