【.Net Core】上传文件-IFormFile

news2024/12/28 21:03:04

文章目录

  • 安全注意事项
  • 存储方案
  • 文件上传方案
    • .NET Core Web APi FormData多文件上传,IFormFile强类型文件灵活绑定
  • 验证
    • 内容验证
    • 文件扩展名验证
    • 文件签名验证
    • 文件名安全
    • 大小验证
    • 使名称属性值与 POST 方法的参数名称匹配
  • 来源

安全注意事项

向用户提供向服务器上传文件的功能时,必须格外小心。 攻击者可能会尝试执行以下操作:

  • 执行拒绝服务攻击。
  • 上传病毒或恶意软件。
  • 以其他方式破坏网络和服务器。

降低成功攻击可能性的安全措施如下:

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

存储方案

常见的文件存储选项有:

  • 数据库
    • 对于小型文件上传,数据库通常快于物理存储(文件系统或网络共享)选项。
    • 相对于物理存储选项,数据库通常更为便利,因为检索数据库记录来获取用户数据可同时提供文件内容(如头像图像)。
    • 相较于使用云数据存储服务,数据库的成本可能更低。
  • 物理存储(文件系统或网络共享)
    • 对于大型文件上传:
      • 数据库限制可能会限制上传的大小。
      • 相对于数据库存储,物理存储通常成本更高。
    • 相较于使用云数据存储服务,物理存储的成本可能更低。
    • 应用的进程必须具有存储位置的读写权限。 切勿授予执行权限。
  • 云数据存储服务(例如 Azure Blob 存储)。
    • 服务通常通过本地解决方案提供提升的可伸缩性和复原能力,而它们往往受单一故障点的影响。
    • 在大型存储基础结构方案中,服务的成本可能更低。

文件上传方案

文件上传方案

缓冲和流式传输是上传文件的两种常见方法。

缓冲

整个文件将读入一个 IFormFile。 IFormFile 是用于处理或保存文件的 C# 表示形式。

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

会将大于 64 KB 的所有单个缓冲文件从内存移到磁盘的临时文件。

用于较大请求的 ASPNETCORE_TEMP 临时文件将写入环境变量中命名的位置。 如果未 ASPNETCORE_TEMP 定义,文件将写入当前用户的临时文件夹。

本主题的以下部分介绍了如何缓冲小型文件:

  • 物理存储
  • Database

流式处理

从多部分请求收到文件,然后应用直接处理或保存它。 流式传输无法显著提高性能。 流式传输可降低上传文件时对内存或磁盘空间的需求。

.NET Core Web APi FormData多文件上传,IFormFile强类型文件灵活绑定

前端使用FormData进行实现批量上传

<!doctype html>

<html>
<head>
    <meta charset="utf-8">

    <title>上传</title>

</head>
<form method="post" id="uploadForm" enctype="multipart/form-data">
    <input type="file" name="file" multiple />
    <input type="button" value="上传" onclick="doUpload()" />
</form>
<body>
    <script src="https://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>
        $(function () {
        });
        function doUpload() {
            var formData = new FormData($("#uploadForm")[0]);
            $.ajax({
                url: 'http://localhost:5000/api/Path/Upload',
                type: 'post',
                data: formData,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (returndata) {
                    console.dir(returndata);
                },
                error: function (returndata) {
                    console.dir(returndata);
                }
            })
        }
    </script>

批量上传选择多个文件:
在这里插入图片描述后端.Net Core 使用 IFormFile 强类型灵活绑定获取文件信息

/// <summary>
        /// 文件上传
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public MethodResult Upload([FromForm(Name = "file")] List<IFormFile> files)
        {
            files.ForEach(file =>
            {
                var fileName = file.FileName;
                string fileExtension = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1);//获取文件名称后缀 
                //保存文件
                var stream = file.OpenReadStream();
                // 把 Stream 转换成 byte[] 
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                // 设置当前流的位置为流的开始 
                stream.Seek(0, SeekOrigin.Begin);
                // 把 byte[] 写入文件 
                FileStream fs = new FileStream("D:\" + file.FileName, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(bytes);
                bw.Close();
                fs.Close();
            });
            return new MethodResult("success", 1);
        }

上传后文件:
在这里插入图片描述

验证

内容验证

将第三方病毒/恶意软件扫描 API 用于上传的内容。

在大容量方案中,在服务器资源上扫描文件较为困难。 若文件扫描导致请求处理性能降低,请考虑将扫描工作卸载到后台服务,该服务可以是在应用服务器之外的服务器上运行的服务。 通常会将卸载的文件保留在隔离区,直至后台病毒扫描程序检查它们。 文件通过检查时,会将相应的文件移到常规的文件存储位置。 通常在执行这些步骤的同时,会提供指示文件扫描状态的数据库记录。 通过此方法,应用和应用服务器可以持续以响应请求为重点。

文件扩展名验证

应在允许的扩展名列表中查找上传的文件的扩展名。 例如:

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
}

文件签名验证

文件的签名由文件开头部分中的前几个字节确定。 可以使用这些字节指示扩展名是否与文件内容匹配。 示例应用检查一些常见文件类型的文件签名。 在下面的示例中,在文件上检查 JPEG 图像的文件签名:
private static readonly Dictionary<string, List<byte[]>> _fileSignature =
new Dictionary<string, List<byte[]>>
{
{ “.jpeg”, new List<byte[]>
{
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
}
},
};

using (var reader = new BinaryReader(uploadedFileData))
{
var signatures = _fileSignature[ext];
var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));

return signatures.Any(signature => 
    headerBytes.Take(signature.Length).SequenceEqual(signature));

}

文件名安全

切勿使用客户端提供的文件名来将文件保存到物理存储。 使用 Path.GetRandomFileName 或 Path.GetTempFileName 为文件创建安全的文件名,以创建完整路径(包括文件名)来执行临时存储。

Razor 自动对属性值执行 HTML 编码以进行显示。 以下代码安全可用:

@foreach (var file in Model.DatabaseFiles) {
    <tr>
        <td>
            @file.UntrustedName
        </td>
    </tr>
}

大小验证

限制上传的文件的大小。

在示例应用中,文件大小限制为 2 MB(以字节为单位)。 通过 appsettings.json 文件中的配置来提供此限制:

{
  "FileSizeLimit": 2097152
}

将 FileSizeLimit 注入到 PageModel 类:

public class BufferedSingleFileUploadPhysicalModel : PageModel
{
    private readonly long _fileSizeLimit;

    public BufferedSingleFileUploadPhysicalModel(IConfiguration config)
    {
        _fileSizeLimit = config.GetValue<long>("FileSizeLimit");
    }

    ...
}

文件大小超出限制时,将拒绝文件:

if (formFile.Length > _fileSizeLimit)
{
    // The file is too large ... discontinue processing the file
}

使名称属性值与 POST 方法的参数名称匹配

在发布窗体数据或直接使用 JavaScript 的 FormData 的非 Razor 窗体中,窗体元素或 FormData 中指定的名称必须与控制器操作中的参数名称相匹配。

在以下示例中

使用 <input> 元素时,将 name 属性设置为值 battlePlans:

<input type="file" name="battlePlans" multiple>

使用 JavaScript FormData 时,将名称设置为值 battlePlans:

var formData = new FormData();

for (var file in files) {
  formData.append("battlePlans", file, file.name);
}

将匹配的名称用于 C# 方法的参数 (battlePlans)
对于名为 Upload 的 Razor Pages 页面处理程序方法:

public async Task<IActionResult> OnPostUploadAsync(List<IFormFile> battlePlans)

对于 MVC POST 控制器操作方法:

public async Task<IActionResult> Post(List<IFormFile> battlePlans)

来源

.NET Core Web APi FormData多文件上传,IFormFile强类型文件灵活绑定
在 ASP.NET Core 中上传文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/31974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openfeign调用文件服务的文件上传接口报错:Current request is not a multipart request

今天在用Swagger测试项目中文件服务的文件上传接口时发现接口调用异常。 异常展示 笔者这里罗列下Swagger上的错误显示、文件服务的异常以及服务调用方的异常。 【Swagger的异常】 【服务调用方的控制台异常】 【文件服务的控制台异常】 代码展示 【服务调用方的Controller…

KMP算法(求解字符串匹配)

提示&#xff1a;可搭配B站比特大博哥视频学习&#xff1a;传送门 &#xff08;点击&#xff09; 目录 前言 图解 代码 前言 KMP算法是一种改进的字符串匹配算法&#xff0c;由D.E.Knuth&#xff0c;J.H.Morris和V.R.Pratt提出的&#xff0c;因此人们称它为克努特一莫里斯―…

如何实现办公自动化?

办公自动化&#xff08;OA&#xff09;允许数据在没有人工干预的情况下流动。由于人工操作被排除在外&#xff0c;所以没有人为错误的风险。如今&#xff0c;办公自动化已经发展成无数的自动化和电子工具&#xff0c;改变了人们的工作方式。 办公自动化的好处 企业或多或少依…

jar包的一些事儿

在咱们日常的搬砖过程中&#xff0c;只要你涉及到Java的项目&#xff0c;就不可避免地接触到jar包。而实际开发中&#xff0c;maven等项目管理工具为我们自动地管理jar包以及相关的依赖&#xff0c;让jar包的调用看起来如黑盒一般"密不透风"。今天&#xff0c;让我们…

做音视频开发要掌握哪些知识?

最近有读者留言&#xff0c;说“想转行音视频开发&#xff0c;怎么做”&#xff0c;正巧&#xff0c;前几天我还在某乎上&#xff0c;看到有人在问音视频的学习资料&#xff0c;还是个大一的学生。 想说一句&#xff1a;真有眼光。 如今这个时代&#xff0c;想赚钱&#xff0c;…

前端开发——HTML5新增加的表单属性

1.formactiom属性 对于<input type"submit">、<button type"submit"></button>、<input type"image">元素&#xff0c;都可以指定formcation属性&#xff0c;该属性可以提交到不同的URL。 代码如下&#xff1a; <f…

自动化平台测试开发方案(详解自动化平台开发)

目录&#xff1a;导读 前言 自动化平台开发方案自动化平台开发 功能需求 技术知识点 技术知识点如表所示 自动化平台开发技术栈如图所示。 开发时间计划 投资回报率可视化 后期优化计划 登录功能实现 退出功能实现 使用Django 内置用户认证退出函数logout。 权限功…

Word控件Spire.Doc 【图像形状】教程(4) 用 C# 中的文本替换 Word 中的图像

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

元宇宙|世界人工智能大会之元宇宙论坛:设计篇

Hello&#xff0c;大家好~ 这里是壹脑云科研圈&#xff0c;我是鲤鱼~ 世界人工智能大会&#xff08;WAIC&#xff09;由国家发展和改革委员会、工业和信息化部、科学技术部、国家互联网信息办公室、中国科学院、中国工程院、中国科学技术协会和上海市人民政府共同主办。 大会…

宝宝喝奶粉过敏怎么办?

为了确保喂养过程安全&#xff0c;我们仍然需要首先了解婴儿奶粉过敏的症状&#xff0c;母亲利用这些基本症状来判断婴儿是否对奶粉过敏&#xff0c;以便及时发现婴儿奶粉过敏&#xff0c;找到相应的策略。婴儿奶粉过敏婴儿奶粉过敏&#xff0c;是指婴儿喝配方奶粉后&#xff0…

【STL】string 类

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;为什么要…

一道面试题:JVM老年代空间担保机制

面试问题 昨天面试的时候&#xff0c;面试官问的问题&#xff1a; 什么是老年代空间担保机制&#xff1f;担保的过程是什么&#xff1f;老年代空间担保机制是谁给谁担保&#xff1f;为什么要有老年代空间担保机制&#xff1f;或者说空间担保机制的目的是什么&#xff1f;如果…

APS高级排产可视化设备任务甘特图

甘特图是评价一个高级计划排程系统的最重要指标之一。一方面企业排程结果数据量规模 大&#xff0c;表格形式显示数据非常不直观&#xff0c;必须借助甘特图进行可视化显示。另一方面&#xff0c;在甘特图上面手动调整排程结果&#xff0c;反馈生产实绩&#xff0c;也可大大简化…

为什么要用 Tair 来服务低延时场景 - 从购物车升级说起

「购物车升级」是今年双十一的重要体验提升项目&#xff0c;体现了大淘宝技术人“用技术突破消费者和商家体验天花板”的态度。这是一种敢于不断重新自我审视&#xff0c;然后做出更好选择的存在主义态度。 「体验提升」通常表现在以前需要降级的功能不降级&#xff0c;以前不…

Web3中文|元宇宙购物的兴起

来源 | techrepublic 近半数消费者接受元宇宙购物 根据UserTesting[1]最近的一项调查&#xff0c;42%的消费者打算在今年的节日季中&#xff08;holiday season&#xff1a;从感恩节到“黑五”&#xff0c;再到圣诞与新年&#xff09;进行元宇宙购物&#xff0c;其中88%的消费…

激光雷达数据的25个重要应用介绍

激光雷达是以发射激光束探测目标的位置、速度等特征量的雷达系统。从工作原理上讲&#xff0c;与微波雷达没有根本的区别: 向目标发射探测信号(激光束), 然后将接收到的从目标反射回来的信号 (目标回波) 与发射信号进行比较, 作适当处理后,就可获得目标的有关信息, 如目标距离、…

基于ALOHA MAC方法的蒙特卡罗模拟(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

ES5+ 和 ES6

一、什么是严格模式 JavaScript 除了提供正常模式外&#xff0c;还提供了严格模式&#xff08;strict mode&#xff09;。ES5 的严格模式是采用具有限制性 JavaScript变体的一种方式&#xff0c;即在严格的条件下运行 JS 代码。严格模式在 IE10 以上版本的浏览器中才会被支持&a…

【App自动化测试】(六)移动端自动化中常用的元素定位方式

目录1. Android/iOS基础知识1.1 Android基础知识1.1.1 七大布局1.1.2 四大组件1.1.3 常用控件1.1.4 控件的布局1.2 iOS基础知识1.2.1 iOS介绍1.2.2 布局1.2.3 开发环境2.控件定位2.1 元素定位法2.1.1 dom结构介绍2.1.2 定位方式2.1.3 演示代码2.2 xpath定位2.2.1 xpath的层级定…

Radis基础命令(Hash类型)对field进行的操作

目录 Hash类型 Hash与String比较 Hash类型的常见命令&#xff08;显而易见&#xff0c;在String命令前加入H就是Hash的命令&#xff09; 1.HSET key field value&#xff1a;添加或修改hash类型key的field的值&#xff08;实操举例&#xff09; 2.HGET key field &#xf…