ASP.NET Core MVC 从入门到精通之文件上传

2025-12-13 0 389

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。 经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启动运行,以及命名约定,创建控制器,视图,模型,接收参数,传递数据ViewData,ViewBag,路由,页面布局,wwwroot和客户端库,Razor语法,EnityFrameworkCore与数据库,HttpContext,Request,Response,Session,序列化等内容,今天继续讲解ASP.NET Core MVC 中文件上传等相关内容,仅供学习分享使用。

ASP.NET Core MVC 从入门到精通之文件上传

概述

在实际应用开发中,文件上传是非常常见的功能,文件上传主要分为单文件上传,多文件上传,文件与其他内容混合上传,大文件上传几种情况,本文会分别讲解。

IFormFile

在ASP.NET Core MVC项目中,IFormFile表示使用 HttpRequest 发送的文件,可以用于文件流的接收。将整个文件读入IFormFile。IFormFile是用于处理或保存文件的文件的 C# 表示形式。

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

IFormFile的属性和方法如下:

ASP.NET Core MVC 从入门到精通之文件上传

对于小文件的上传,一般采用IFormFile;大文件上传,采用流式上传,已实现可靠稳定传输。

IWebHostEnvironment 站点环境信息,用于获取站点根目录等内容。

单个文件上传

单文件上传功能主要分为两部分:文件上传视图和后台处理方法。

1. 文件上传视图

首先创建视图,用于单个文件上传。关于视图有两点说明,如下所示:

  1. 文件上传通过form表单,采用post方式,加密类型为multipart/form-data
  2. 文件上传采用input控件,类型为file。

视图代码如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

1 <form method=\"post\" enctype=\"multipart/form-data\" action=\"/File/OneFileUpload\"> 2 <h1>单文件上传</h1> 3 <div> 4 <span>文件:</span> 5 <input type=\"file\" name=\"file\" /> 6 </div> 7 <input type=\"submit\" value=\"上传\" /> 8 </form>

ASP.NET Core MVC 从入门到精通之文件上传

2. 后台处理方法

form提交后台处理方法OneFileUpload,关于处理方法有几点说明,如下所示:

  1. 方法中的参数IFormFile file用于接收客户端上传的文件,其他file和视图中上传控件的name一一对应。如果错误,则无法上传。
  2. _webHostEnvironment 为控制器通过接口注入的IWebHostEnvironment类型的获取站点信息接口,主要用于获取站点根目录。
  3. 调用IFormFile的CopyTo方法进行保存,此方法接收Stream类型的参数。

上传处理代码,如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

 1 /// <summary>  2 /// 单文件上传  3 /// </summary>  4 /// <returns></returns>  5 public IActionResult OneFileUpload(IFormFile file)  6 {  7 var path = Path.Combine(_webHostEnvironment.ContentRootPath, \"uploads\", string.Format(\"{0}_{1}\", DateTime.Now.Ticks, file.FileName));  8 using (FileStream fs = new FileStream(path, FileMode.Create))  9  { 10  file.CopyTo(fs); 11  } 12 return Ok(\"上传成功\"); 13 }

ASP.NET Core MVC 从入门到精通之文件上传

多文件上传

多文件上传表示一次可以上传多个文件。。上传功能主要分为两部分:文件上传视图和后台处理方法。

1. 多文件上传视图

input控件在类型为file时表示文件上传,默认是单个文件上传,通过设置multiple属性,可实现多文件上传。视图代码如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

1 <form method=\"post\" enctype=\"multipart/form-data\" action=\"/File/MoreFileUpload\"> 2 <h1>多文件上传</h1> 3 <div> 4 <span>文件:</span> 5 <input type=\"file\" name=\"files\" multiple /> 6 </div> 7 <input type=\"submit\" value=\"上传\" /> 8 </form>

ASP.NET Core MVC 从入门到精通之文件上传

2. 多文件后台处理方法

多个文件上传,参数为IFormFile数组类型,可以接受上传文件列表,然后循环获取并进行保存即可。如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

 1 /// <summary>  2 /// 多文件上传  3 /// </summary>  4 /// <returns></returns>  5 public IActionResult MoreFileUpload(IFormFile[] files)  6 {  7 foreach (var file in files)  8  {  9 var path = Path.Combine(_webHostEnvironment.ContentRootPath, \"uploads\", string.Format(\"{0}_{1}\", DateTime.Now.Ticks, file.FileName)); 10 using (FileStream fs = new FileStream(path, FileMode.Create)) 11  { 12  file.CopyTo(fs); 13  } 14  } 15 16 return Ok(\"上传成功\"); 17 }

ASP.NET Core MVC 从入门到精通之文件上传

文件文本混合上传

在实际应用中,文件上传只是一部分,还需要搭配其他的文本说明,如录入产品信息,并上传附件等。

1. 创建模型

在Product中,包含两个属性,一个字符串类型的Name,用于绑定名称,一个IFormFile类型的File,用于上传文件。如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

1 namespace DemoCoreMVC.Models 2 { 3  public class Product 4  { 5  public string Name { get; set; } 6 7  public IFormFile File { get; set; } 8  } 9 }

ASP.NET Core MVC 从入门到精通之文件上传

2. 视图绑定模型

在视图最顶部,为视图指定模型,如下所示:

1 @model DemoCoreMVC.Models.Product

3. 混合文本文件上传视图

在form表单中,除了文件上传控件,还有一个文件框,用于输入名称。其中控件name和模型相对应。如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

 1 <form method=\"post\" enctype=\"multipart/form-data\" action=\"/File/FileWithContentUpload\">  2 <h1>文件,文本混合上传</h1>  3 <div>  4 <span>名称:</span>  5 <input type=\"text\" name=\"Name\" />  6 </div>  7 <div>  8 <span>文件:</span>  9 <input type=\"file\" name=\"File\" /> 10 </div> 11 <input type=\"submit\" value=\"上传\" /> 12 </form>

ASP.NET Core MVC 从入门到精通之文件上传

4. 后台处理方法

文件文本混合上传,参数为模型Product,通过属性匹配接收参数,然后获取属性File对应的内存流进行保存即可。如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

 1 /// <summary>  2 /// 文件内容混合上传  3 /// </summary>  4 /// <returns></returns>  5 public IActionResult FileWithContentUpload(Product product)  6 {  7 var file = product.File;  8 var path = Path.Combine(_webHostEnvironment.ContentRootPath, \"uploads\", string.Format(\"{0}_{1}\", DateTime.Now.Ticks, file.FileName));  9 using (FileStream fs = new FileStream(path, FileMode.Create)) 10  { 11  file.CopyTo(fs); 12  } 13 return Ok($\"{product.Name} 上传成功\"); 14 }

ASP.NET Core MVC 从入门到精通之文件上传

大文件上传

首先如何界定大文件/小文件,并没有统一的标准。根据官网相关参数说明:

  1. 默认情况下,HttpRequest.Form不会缓冲整个请求正文 (BufferBody) ,但会缓冲包含的任何多部分表单文件。
  2. MultipartBodyLengthLimit是缓冲表单文件的最大大小,默认值为 128MB。
  3. MemoryBufferThreshold指示在转换为磁盘上的缓冲区文件之前,内存中的文件缓冲量,默认为 64KB。
  4. MemoryBufferThreshold充当小型和大型文件之间的边界,这些文件根据应用资源和方案而引发或降低。

大文件上传采用流式传输,可降低上传文件时对内存或磁盘空间的需求。

1. 创建视图

大文件和小文件上传在视图上并无差别,只是后台处理方法不同,如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

1 <form method=\"post\" enctype=\"multipart/form-data\" action=\"/File/BigFileUpload\"> 2 <h1>大文件上传</h1> 3 <div> 4 <span>文件:</span> 5 <input type=\"file\" name=\"file\" /> 6 </div> 7 <input type=\"submit\" value=\"上传\" /> 8 </form>

ASP.NET Core MVC 从入门到精通之文件上传

2. 后台处理方法

首先创建大文件上传帮助类MultipartRequestHelper,如下所示:

ASP.NET Core MVC 从入门到精通之文件上传

 1 using System;  2 using System.IO;  3 using Microsoft.Net.Http.Headers;  4 namespace DemoCoreMVC  5 {  6 public static class MultipartRequestHelper  7  {  8 // Content-Type: multipart/form-data; boundary=\"----WebKitFormBoundarymx2fSWqWSd0OxQqq\"  9 public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) 10  { 11 var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; 12 13 if (string.IsNullOrWhiteSpace(boundary)) 14  { 15 throw new InvalidDataException(\"Missing content-type boundary.\"); 16  } 17 18 if (boundary.Length > lengthLimit) 19  { 20 throw new InvalidDataException( 21 $\"Multipart boundary length limit {lengthLimit} exceeded.\"); 22  } 23 24 return boundary; 25  } 26 27 public static bool IsMultipartContentType(string contentType) 28  { 29 return !string.IsNullOrEmpty(contentType) 30 && contentType.IndexOf(\"multipart/\", StringComparison.OrdinalIgnoreCase) >= 0; 31  } 32 33 public static bool HasFileContentDisposition(ContentDispositionHeaderValue contentDisposition) 34  { 35 // Content-Disposition: form-data; name=\"myfile1\"; filename=\"Misc 002.jpg\" 36 return contentDisposition != null 37 && contentDisposition.DispositionType.Equals(\"form-data\") 38 && (!string.IsNullOrEmpty(contentDisposition.FileName.Value) 39 || !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value)); 40  } 41 42 // 如果一个section的Header是: Content-Disposition: form-data; name=\"myfile1\"; filename=\"F:\\Misc 002.jpg\" 43 // 那么本方法返回: Misc 002.jpg 44 public static string GetFileName(ContentDispositionHeaderValue contentDisposition) 45  { 46 return Path.GetFileName(contentDisposition.FileName.Value); 47  } 48 49  } 50 }

ASP.NET Core MVC 从入门到精通之文件上传

处理方法BigFileUploadAsync,关于Action说明,如下所示:

Action中要进行DisableRequestSizeLimit特性说明,否则会有大小限制【InvalidDataException: Multipart body length limit 16384 exceeded】。

在该操作中,使用MultipartReader读取窗体的内容,它会读取每个单独的MultipartSection,从而根据需要处理文件或存储内容。 读取多部分节后,该操作会执行自己的模型绑定。

ASP.NET Core MVC 从入门到精通之文件上传

 1 /// <summary>  2 /// 大文件上传  3 /// </summary>  4 /// <returns></returns>  5 [DisableRequestSizeLimit]  6 public async Task<IActionResult> BigFileUploadAsync()  7 {  8 var contentType = Request.ContentType;  9 if (!MultipartRequestHelper.IsMultipartContentType(contentType)) 10  { 11 ModelState.AddModelError(\"File\", 12 $\"上传文件类型不对.\"); 13 return BadRequest(ModelState); 14  } 15 var path = Path.Combine(_webHostEnvironment.ContentRootPath, \"uploads\"); 16 17 var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit); 18 19 var reader = new MultipartReader(boundary, HttpContext.Request.Body); 20 21 var section = await reader.ReadNextSectionAsync(); 22 23 while (section != null) 24  { 25 var hasContentDispositionHeader = 26  ContentDispositionHeaderValue.TryParse( 27 section.ContentDisposition, out var contentDisposition); 28 29 if (hasContentDispositionHeader) 30  { 31 if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition)) 32  { 33 ModelState.AddModelError(\"File\", 34 $\"The request couldn\'t be processed (Error 2).\"); 35 36 return BadRequest(ModelState); 37  } 38 else 39  { 40 var fileName = MultipartRequestHelper.GetFileName(contentDisposition); 41 var loadBufferBytes = 1024;//这个是每一次从Http请求的section中读出文件数据的大小,单位是Byte即字节,这里设置为1024的意思是,每次从Http请求的section数据流中读取出1024字节的数据到服务器内存中,然后写入下面targetFileStream的文件流中,可以根据服务器的内存大小调整这个值。这样就避免了一次加载所有上传文件的数据到服务器内存中,导致服务器崩溃。 42 43 using (var targetFileStream = new FileStream(path + \"\\\\\" + string.Format(\"{0}_{1}\", DateTime.Now.Ticks, fileName), FileMode.Create, FileAccess.ReadWrite)) 44  { 45 using (section.Body) 46  { 47 //section.Body是System.IO.Stream类型,表示的是Http请求中一个section的数据流,从该数据流中可以读出每一个section的全部数据,所以我们下面也可以不用section.Body.CopyToAsync方法,而是在一个循环中用section.Body.Read方法自己读出数据(如果section.Body.Read方法返回0,表示数据流已经到末尾,数据已经全部都读取完了),再将数据写入到targetFileStream 48 await section.Body.CopyToAsync(targetFileStream, loadBufferBytes); 49  } 50  } 51  } 52  } 53 section = await reader.ReadNextSectionAsync(); 54  } 55 return Ok(\"上传成功\"); 56 }

ASP.NET Core MVC 从入门到精通之文件上传

注意:在文件上传功能中,上传后的文件一般都要进行重命名的,否则如何客户端上传相同名称的文件,则可能会被覆盖。在本例中,在原文件前面加上了时间戳,以减少重复的概率。

文件上传校验

在实际开发中,为了避免客户端上传不满足条件的文件,一般都会进行校验。

  1. 文件扩展名验证:应在允许的扩展名列表中查找上传的文件的扩展名。
  2. 文件签名验证:文件的签名由文件开头部分中的前几个字节确定。 可以使用这些字节指示扩展名是否与文件内容匹配。 示例应用检查一些常见文件类型的文件签名。
  3. 文件名安全:切勿使用客户端提供的文件名来将文件保存到物理存储。
  4. 文件大小验证:限制上传的文件的大小。

文件上传安全

为避免文件上传功能造成攻击可能性,常规安全措施如下:

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

参考文章

本篇文章主要参考内容如下:

1. 官方文档:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/models/file-uploads?view=aspnetcore-6.0

以上就是ASP.NET Core MVC从入门到精通之文件上传的全部内容。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 ASP.NET Core MVC 从入门到精通之文件上传 https://www.zuozi.net/36234.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务