更新记录
转载请注明出处:
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)
标签:files,Core,ASP,string,文件,get,大小,NET,上传
From: https://www.cnblogs.com/cqpanda/p/16882681.html