ASP.NET MVC 文件上传和文件下载 以及 文件下载的几种方法
1、序言
最近项目中需要用到这个功能点,但是网上下载的时候总是出现乱码。所以趁着这个时间自己整理出了一份,以后需要的时候就直接看自己的博客就行了。已经测试过:在谷歌、火狐、IE等浏览器上都不会出现乱码问题。
2、结果展示
2.1、上传文件成功界面
2.2、下载文件成功界面
3、上传文件代码
3.1、View代码
![](/assets/blank.gif)
@model System.Web.HttpContextBase @{ViewBag.Title = "上传文件"; } <h2>上传文件</h2> <br /> <br /> @*new { enctype = "multipart/form-data" }比不可少,否则上传文件不会成功 *@ @using (Html.BeginForm("Upload", "UploadFile", FormMethod.Post, new { enctype = "multipart/form-data" })) {<text>选择上传文件:</text><input name="file" type="file" id="file" /><br /><br /><input type="submit" name="Upload" value="Upload" /> }
![](/assets/blank.gif)
3.2、Controller代码
![](/assets/blank.gif)
[HttpPost]public ActionResult Upload(FormCollection form){if (Request.Files.Count == 0){//Request.Files.Count 文件数为0上传不成功return View();}var file = Request.Files[0];if (file.ContentLength == 0){//文件大小大(以字节为单位)为0时,做一些操作return View();}else{//文件大小不为0file = Request.Files[0];//保存成自己的文件全路径,newfile就是你上传后保存的文件,//服务器上的UpLoadFile文件夹必须有读写权限string target = Server.MapPath("/")+("/Mock/Learning/");//取得目标文件夹的路径string filename = file.FileName;//取得文件名字string path = target + filename;//获取存储的目标地址 file.SaveAs(path);}return View();}
![](/assets/blank.gif)
4、下载文件代码
4.1、View代码
<a href="/DownloadFile/Download?filePath=@ViewBag.Value&fileName='小王子.pdf'">下载</a>
4.2、Controller代码
![](/assets/blank.gif)
public ActionResult Download(string filePath, string fileName){Encoding encoding;string outputFileName = null;fileName = fileName.Replace("'", "");string browser =Request.UserAgent.ToUpper();if (browser.Contains("MS") == true && browser.Contains("IE") == true){outputFileName = HttpUtility.UrlEncode(fileName);encoding =Encoding.Default;}else if (browser.Contains("FIREFOX") == true){outputFileName = fileName;encoding =Encoding.GetEncoding("GB2312");}else{outputFileName = HttpUtility.UrlEncode(fileName);encoding = Encoding.Default;}FileStream fs = new FileStream(filePath, FileMode.Open);byte[] bytes = new byte[(int)fs.Length];fs.Read(bytes, 0, bytes.Length);fs.Close();Response.Charset = "UTF-8";Response.ContentType = "application/octet-stream";Response.ContentEncoding = encoding;Response.AddHeader("Content-Disposition", "attachment; filename=" + outputFileName);Response.BinaryWrite(bytes);Response.Flush();Response.End();return new EmptyResult();}
![](/assets/blank.gif)
在ASP.net MVC 中有几种下载文件的方法
前提:要下载的文件必须是在服务器目录中的,至于不在web项目server目录中的文件下载我不知道,但是还挺想了解的。
第一种:最简单的超链接方法,<a>标签的href直接指向目标文件地址,这样容易暴露地址造成盗链,这里就不说了
第二种:后台下载
在后台下载中又可以细分为几种下载方式
首先,在前台,我们需要一个<a>标签
<a href="~/Home/download">Click to get file</a>
Home为controller,download为action。
如果需要传一些参数,可以:
<a href="~/Home/download?id=1">Click to get file</a>
在后台:
(1)返回filestream
![](/assets/blank.gif)
public FileStreamResult download() {string fileName = "aaa.txt";//客户端保存的文件名string filePath = Server.MapPath("~/Document/123.txt");//路径return File(new FileStream(filePath, FileMode.Open), "text/plain", fileName); }
![](/assets/blank.gif)
其中:“text/plain”是文件MIME类型
(2)返回file
public FileResult download(){string filePath = Server.MapPath("~/Document/123.txt");//路径return File(filePath, "text/plain", "welcome.txt"); //welcome.txt是客户端保存的名字}
(3)TransmitFile方法
![](/assets/blank.gif)
1 public void download() 2 { 3 string fileName = "aaa.txt";//客户端保存的文件名 4 string filePath = Server.MapPath("~/Document/123.txt");//路径 5 FileInfo fileinfo = new FileInfo(filePath); 6 Response.Clear(); //清除缓冲区流中的所有内容输出 7 Response.ClearContent(); //清除缓冲区流中的所有内容输出 8 Response.ClearHeaders(); //清除缓冲区流中的所有头 9 Response.Buffer = true; //该值指示是否缓冲输出,并在完成处理整个响应之后将其发送 10 Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); 11 Response.AddHeader("Content-Length",fileinfo.Length.ToString()); 12 Response.AddHeader("Content-Transfer-Encoding", "binary"); 13 Response.ContentType = "application/unknow"; //获取或设置输出流的 HTTP MIME 类型 14 Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); //获取或设置输出流的 HTTP 字符集 15 Response.TransmitFile(filePath); 16 Response.End(); 17 }
![](/assets/blank.gif)
(4)Response分块下载
![](/assets/blank.gif)
1 public void download() 2 { 3 string fileName = "aaa.txt";//客户端保存的文件名 4 string filePath = Server.MapPath("~/Document/123.txt");//路径 5 6 System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath); 7 if (fileInfo.Exists == true) 8 { 9 const long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力 10 byte[] buffer = new byte[ChunkSize]; 11 12 Response.Clear(); 13 System.IO.FileStream iStream = System.IO.File.OpenRead(filePath); 14 long dataLengthToRead = iStream.Length;//获取下载的文件总大小 15 Response.ContentType = "application/octet-stream"; 16 Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName)); 17 while (dataLengthToRead > 0 && Response.IsClientConnected) 18 { 19 int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小 20 Response.OutputStream.Write(buffer, 0, lengthRead); 21 Response.Flush(); 22 dataLengthToRead = dataLengthToRead - lengthRead; 23 } 24 Response.Close(); 25 } 26 }
![](/assets/blank.gif)
<input>+ajax方法
要重点说说这个方法,ajax返回不了文件流,所以说用ajax调用上面任意一种后台方法都要出问题,下载不了文件。
所以,只能让后台返回所需下载文件的url地址,然后调用windows.location.href。
优点:ajax可以传好几个参数(当然以json形式),传100个都无所谓。你要是用<a href="网址?参数=值"></a>的方法传100得写死。。。(公司需求,至少要传100多个参数)
缺点:支持下载exe,rar,msi等类型文件。对于txt则会直接打开,慎用!对于其他不常用的类型文件则直接报错。
所以我的建议是得到多个参数,通过数据库找到所有需要下载的文件然后压缩打包,然后返回url下载。(你要是一个一个给用户下,用户都疯了)
!那么问题又来了,C#怎么用代码实现将本地的一些文件打包压缩到服务器目录下呢?这我不知道。
因为你只是单纯的放在目录文件夹下没有用的,我们平时在服务器某目录下添加某一个文件都是右键,添加XXX项这样,这样才能真正的将文件放在服务器中。
可是纯代码该怎么实现呢??
* 可能的解决方法:先在项目目录下放一个空的rar文件或者没什么功能的exe,msi文件,然后在后台打包完一些文件后去替换它,不知道可行不。
(1)首先清空原压缩包中的内容
(2)将文件压缩到压缩包中
(3)返回 XXX.rar
前端:
<input type="button" id="downloadbutton"/>
ajax:
![](/assets/blank.gif)
$("#downloadbutton").click(function () {$.ajax({type: "GET",url: "/Home/download",data: { id: "1" },dataType:"json",success: function (result) {window.location.target = "_blank";window.location.href = result; }})})
![](/assets/blank.gif)
后台:
public string download(int id){string filePath = "Document/123.msi";//路径return filePath;}
这里,id是没有什么作用的,后台就别用什么server.Mappath了,肯定错。直接写服务器项目文件夹/文件名 即可。
前言
这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看。
Upload File(一)
我们在默认创建的项目中的Home控制器下添加如下:
![](/assets/blank.gif)
public ActionResult UploadFile(){return View();}[HttpPost]public ActionResult UploadFile(HttpPostedFileBase file){var fileName = file.FileName;var filePath = Server.MapPath(string.Format("~/{0}", "File"));file.SaveAs(Path.Combine(filePath, fileName));return View();}
![](/assets/blank.gif)
在 UploadFile 视图中添加上如下:
<form action="/Home/UploadFile" method="post" enctype="multipart/form-data"><input type="file" name="file" /><br /><input type="submit" value="提交" /> </form>
有关视图中我们就不必多说,只需明白如下两点:
(1)在后台利用HttpPostedFileBase来接收上传文件,该类为一个抽象类,但在ASP.NET Web Form却没有此类,此类的出现是为了更好的进行单元测试。
(2)在视图中文件类型的name要和后台接收文件的参数一致。
接下来我们进行演示看看结果:
上述我们简单的上传了一个Excel文件,下面我们通过强类型视图以及模型验证来强化上传。
Upload File(二)
我们创建如下BlogModel类:
![](/assets/blank.gif)
public class BlogModel{[Display(Name = "博客名称")][Required(ErrorMessage = "请输入你的博客名称!")]public string BlogName { get; set; }[Display(Name = "博客地址")][Required(ErrorMessage = "请输入你的博客地址!")]public string BlogAddress { get; set; }[Display(Name = "博客图片")][Required(ErrorMessage = "请上传你的博客图片!")] [ValidateFile]public HttpPostedFileBase BlogPhoto { get; set; }}
![](/assets/blank.gif)
上述未有验证文件的特性,只能自定义文件特性,如下:
![](/assets/blank.gif)
public class ValidateFileAttribute : ValidationAttribute{public override bool IsValid(object value){int MaxContentLength = 1024 * 1024 * 4;string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".pdf" };var file = value as HttpPostedFileBase;if (file == null)return false;else if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.')))){ErrorMessage = "请上传你的博客图片类型: " + string.Join(", ", AllowedFileExtensions);return false;}else if (file.ContentLength > MaxContentLength){ErrorMessage = "上传图片过大,不能超过4兆 : " + (MaxContentLength / 1024).ToString() + "MB";return false;}elsereturn true;}}
![](/assets/blank.gif)
我们可以任意设置上传的文件大小,我们设置为40兆,在配置文件中我们知道 maxRequestLength = 4096 默认是4兆,当然我们可以改变其默认设置。
<httpRuntime targetFramework="4.5" executionTimeout="1100" maxRequestLength="40960" />
此时我们接着在控制器中修改上述上传的方法:
![](/assets/blank.gif)
[HttpPost]public ActionResult UploadFile(BlogModel bModel){if (ModelState.IsValid){var fileName = bModel.BlogPhoto.FileName;var filePath = Server.MapPath(string.Format("~/{0}", "File"));bModel.BlogPhoto.SaveAs(Path.Combine(filePath, fileName));ModelState.Clear();} return View();}
![](/assets/blank.gif)
我们接下来看看效果:
咋回事,出状况了看来是我们的文件过大的原因,看了下该文件有接近45兆,而我们却设置的是40兆,于是乎继续在配置文件中去修改文件大小,但是结果还是一样。我们继续仔细看看该结果的提示,根据提示去找到配置文件下的节点再试试,我们在 syste.webServer 节点下设置为2G:
![](/assets/blank.gif)
<security><requestFiltering><requestLimits maxAllowedContentLength="2147483647"></requestLimits></requestFiltering></security>
![](/assets/blank.gif)
结果就好使了,查了查也有遇到类似问题的人,貌似只有给个结果,却没有给解释,为什么在 httpRuntime 中设置不行,但是有些这样设置是正确的,这是什么原因?最终找到了答案:
(1)在IIS 5和IIS 6中,默认文件上传的最大为4兆,当上传的文件大小超过4兆时,则会得到错误信息,但是我们通过如下来设置文件大小。
<system.web><httpRuntime maxRequestLength="2147483647" executionTimeout="100000" /> </system.web>
(2)在IIS 7中,默认文件上传的最大为28.6兆,当超过其默认设置大小,同样会得到错误信息,但是我们却可以通过如下来设置文件上传大小。
![](/assets/blank.gif)
<system.webServer><security><requestFiltering><requestLimits maxAllowedContentLength="2147483647" /></requestFiltering></security> </system.webServer>
![](/assets/blank.gif)
【类推的话,个人觉得可能是在IIS 7+以上都是通过如上述IIS 7来设置文件上传大小】
虽然我们在服务器端对其进行验证,但是我们觉得这样还是不能保险,我们继续在客户端对其上传的图片类型和大小进行验证。
(1)利用强类型视图给出视图代码:
![](/assets/blank.gif)
<style type="text/css">.field-validation-error {color: red;} </style> <form id="uploadFileSub" action="/Home/UploadFile" method="post" enctype="multipart/form-data"><fieldset><legend></legend><ul class="lifile"><li>@Html.LabelFor(m => m.BlogName)<br />@Html.TextBoxFor(m => m.BlogName, new { maxlength = 50 })@Html.ValidationMessageFor(m => m.BlogName)</li><li>@Html.LabelFor(m => m.BlogAddress)<br />@Html.TextBoxFor(m => m.BlogAddress, new { maxlength = 200 })@Html.ValidationMessageFor(m => m.BlogAddress)<br /></li><li>@Html.LabelFor(m => m.BlogPhoto)@Html.TextBoxFor(m => m.BlogPhoto, new { type = "file" })@Html.ValidationMessageFor(m => m.BlogPhoto)<span id="warning" style="color:red;font-size:large;"></span></li><li><input type="submit" value="提交" /></li></ul></fieldset> </form>
![](/assets/blank.gif)
(2)利用脚本获取上传文件大小:
![](/assets/blank.gif)
function GetFileSize(fileid) {var fileSize = 0;fileSize = $("#" + fileid)[0].files[0].size;fileSize = fileSize / 1048576;return fileSize;}
![](/assets/blank.gif)
(3)根据上传的路径获取文件名称:
![](/assets/blank.gif)
function getNameFromPath(strFilepath) {var objRE = new RegExp(/([^\/\\]+)$/);var strName = objRE.exec(strFilepath);if (strName == null) {return null;}else {return strName[0];}}
![](/assets/blank.gif)
(4)当更换文件时触发Change事件对其文件类型和文件大小进行验证:
![](/assets/blank.gif)
$("#BlogPhoto").change(function () {var file = getNameFromPath($(this).val());if (file != null) {var errors = $(document).find(".field-validation-error");$.each(errors, function (k, v) {if ($(v).attr("data-valmsg-for") === "BlogPhoto") {$(v).hide();}});var extension = file.substr((file.lastIndexOf('.') + 1));switch (extension) {case 'jpg':case 'png':case 'gif':case 'pdf':fileTypeBool = false;break;default:fileTypeBool = true;}}if (fileTypeBool) {$("#warning").html("只能上传扩展名为jpg,png,gif,pdf的文件!");return false;}else {var size = GetFileSize('BlogPhoto');if (size > 4) {fileSizeBool = true;$("#warning").html("上传文件已经超过4兆!");} else {fileSizeBool = false;}}});
![](/assets/blank.gif)
(5)当点击提交按钮时对其进行文件进行验证:
![](/assets/blank.gif)
$("#uploadFileSub").submit(function () {$("input[type='text']").each(function (k, v) {if ($(v).length) {$(v).siblings("span").hide();}});if (fileTypeBool || fileSizeBool) {return false;}});
![](/assets/blank.gif)
【注意】上述对于验证不是太完整,但是基本的架子已经给出。
接下来我们来完整的演示整个过程。
上述我们一直是利用的纯HTML代码,当然也可以利用MVC的扩展方法来进行,如下(最终渲染的还是表单,本质上是一致的,就不做过多探讨了)
![](/assets/blank.gif)
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" id="file" name="file" /><input type="submit" value="提交" /> }
![](/assets/blank.gif)
结语
这一节我们比较详细的讲述了在MVC中如何进行文件的上传,但是我们还有一点未曾讲到,则是利用流来将如我们上述的图片转换成字节来插入到数据库中。有关上传可以参考园友Insus.NET对此利用流来上传。
原文地址:https://www.cnblogs.com/CreateMyself/p/5414200.html
ASP.NET MVC 文件上传和文件下载 以及 文件下载的几种方法相关推荐
- asp.net mvc文件上传
文件上传到文件夹下: @using (Html.BeginForm("FileUp","Home",FormMethod.Post,new { enctype ...
- [转载]ASP.NET Core文件上传与下载(多种上传方式)
ASP.NET Core文件上传与下载(多种上传方式) 前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在整理 ...
- ASP.NET Core文件上传IFormFile于Request.Body的羁绊
前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式[1]中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题, ...
- spring mvc文件上传小例子
spring mvc文件上传小例子 1.jsp页面 <%@page contentType="text/html;charset=UTF-8"%> <%@page ...
- ASP.NET中文件上传下载方法集合
asp.net 2008-08-23 21:10:35 阅读0 评论0 字号:大中小 订阅 ASP.NET中文件上传下载方法集合 文件的上传下载是我们在实际项目开发过程中经常需要用到的技术,这里给 ...
- Spring MVC文件上传示例教程 - 单个和多个文件
Spring MVC文件上传示例教程 - 单个和多个文件 文件上传是任何Web应用程序中非常常见的任务.我们之前已经看过如何在Servlet和Struts2文件上传中上传文件.今天我们将学习Sprin ...
- MVC文件上传07-使用客户端jQuery-File-Upload插件和服务端Backload组件裁剪上传图片...
本篇通过在配置文件中设置,对上传图片修剪后保存到指定文件夹. 相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小 MVC文件上传02-使用HttpPostedFileB ...
- 服务器 上传文件 杀毒,一种实现文件上传网站后自动进行杀毒的方法及系统
1. 一种实现文件上传网站后自动进行杀毒的系统,其特征在于,包括: 服务器端监控模块,用于对每一个上传到服务器的文件进行监控: 服务器端的杀毒模块,用于对上传到服务器的文件进行病毒查杀: 位于服务器端 ...
- php104.tmp,ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
这是修改之前的代码 if(!empty($_FILES)){ if(!empty($_FILES[org_positive])){ $org_positive = request()->file ...
最新文章
- java学习笔记4--对象的初始化与回收
- Linux进程间通信——使用共享内存
- C/C++的64位整型
- LeetCode 334. 递增的三元子序列
- VUE项目中使用this.$forceUpdate()强制页面重新渲染
- 【Kafka】Kafka ArithmeticException: / by zer
- rhel 6.4 增加光盘为yum repo
- java 静态方法的使用_java的静态方法的使用
- (21)pandas.drop与dropna方法
- SVM多分类算法-一对一
- 解决win7 svchost占用CPU过高的问题
- 机房合作—SVN skipped remains conflicted
- ios13一直在估算剩余时间怎么办
- 【HTML】HTML网页设计-----游戏网页设计
- Unity特效基础:粒子效果面板
- 服务器运维KPI指标,IT运维包括哪些内容,考核标准是什么
- SQLConverter SQLserver数据库转换为SQLLite数据库
- 微信视频号怎么涨粉?我总结了5条经验_
- 吴师兄领证之前谈了多少个女朋友?
- 南开大学 软件学院 操作系统 李旭东老师 复习
热门文章
- SQL查找是否“存在“
- 贪心算法之——摘枇杷(nyoj680)(贪心+二分搜索)
- 3DMax—吹风机建模
- joomla joomla模板下载地址汇总
- unity重置天下霸图之进度汇总
- 暴雪和黑客的战争三:黑客的反击
- 轻松学c语言编程.pdf等,轻松学编程:轻松学C语言编程 PDF
- com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.
- UltraEdit文本编辑器丨功能介绍
- delmia机器人示教01