1、序言

最近项目中需要用到这个功能点,但是网上下载的时候总是出现乱码。所以趁着这个时间自己整理出了一份,以后需要的时候就直接看自己的博客就行了。已经测试过:在谷歌、火狐、IE等浏览器上都不会出现乱码问题。

2、结果展示

2.1、上传文件成功界面

2.2、下载文件成功界面

3、上传文件代码

3.1、View代码

@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" />
}

3.2、Controller代码

[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();}

4、下载文件代码

4.1、View代码

<a href="/DownloadFile/Download?filePath=@ViewBag.Value&fileName='小王子.pdf'">下载</a>

4.2、Controller代码

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();}

在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

public FileStreamResult download()
{string fileName = "aaa.txt";//客户端保存的文件名string filePath = Server.MapPath("~/Document/123.txt");//路径return File(new FileStream(filePath, FileMode.Open), "text/plain",   fileName);
}

其中:“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方法

 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 }

(4)Response分块下载

 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         }

<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:

$("#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;                      }})})

后台:

public string download(int id){string filePath = "Document/123.msi";//路径return filePath;}

这里,id是没有什么作用的,后台就别用什么server.Mappath了,肯定错。直接写服务器项目文件夹/文件名 即可。

前言

这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看。

Upload File(一)

我们在默认创建的项目中的Home控制器下添加如下:

        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();}

在 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类:

    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; }}

上述未有验证文件的特性,只能自定义文件特性,如下:

    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;}}

我们可以任意设置上传的文件大小,我们设置为40兆,在配置文件中我们知道 maxRequestLength = 4096 默认是4兆,当然我们可以改变其默认设置。

    <httpRuntime targetFramework="4.5" executionTimeout="1100"  maxRequestLength="40960" />

此时我们接着在控制器中修改上述上传的方法:

        [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();}

我们接下来看看效果:

咋回事,出状况了看来是我们的文件过大的原因,看了下该文件有接近45兆,而我们却设置的是40兆,于是乎继续在配置文件中去修改文件大小,但是结果还是一样。我们继续仔细看看该结果的提示,根据提示去找到配置文件下的节点再试试,我们在 syste.webServer 节点下设置为2G:

    <security><requestFiltering><requestLimits maxAllowedContentLength="2147483647"></requestLimits></requestFiltering></security>

结果就好使了,查了查也有遇到类似问题的人,貌似只有给个结果,却没有给解释,为什么在 httpRuntime 中设置不行,但是有些这样设置是正确的,这是什么原因?最终找到了答案:

(1)在IIS 5和IIS 6中,默认文件上传的最大为4兆,当上传的文件大小超过4兆时,则会得到错误信息,但是我们通过如下来设置文件大小。

<system.web><httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

(2)在IIS 7中,默认文件上传的最大为28.6兆,当超过其默认设置大小,同样会得到错误信息,但是我们却可以通过如下来设置文件上传大小。

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

【类推的话,个人觉得可能是在IIS 7+以上都是通过如上述IIS 7来设置文件上传大小】

虽然我们在服务器端对其进行验证,但是我们觉得这样还是不能保险,我们继续在客户端对其上传的图片类型和大小进行验证。

(1)利用强类型视图给出视图代码:

<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>

(2)利用脚本获取上传文件大小:

    function GetFileSize(fileid) {var fileSize = 0;fileSize = $("#" + fileid)[0].files[0].size;fileSize = fileSize / 1048576;return fileSize;}

(3)根据上传的路径获取文件名称:

    function getNameFromPath(strFilepath) {var objRE = new RegExp(/([^\/\\]+)$/);var strName = objRE.exec(strFilepath);if (strName == null) {return null;}else {return strName[0];}}

(4)当更换文件时触发Change事件对其文件类型和文件大小进行验证:

        $("#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;}}});

(5)当点击提交按钮时对其进行文件进行验证:

        $("#uploadFileSub").submit(function () {$("input[type='text']").each(function (k, v) {if ($(v).length) {$(v).siblings("span").hide();}});if (fileTypeBool || fileSizeBool) {return false;}});

【注意】上述对于验证不是太完整,但是基本的架子已经给出。

接下来我们来完整的演示整个过程。

上述我们一直是利用的纯HTML代码,当然也可以利用MVC的扩展方法来进行,如下(最终渲染的还是表单,本质上是一致的,就不做过多探讨了)

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ <input type="file" id="file" name="file" /><input type="submit" value="提交" />
}

结语

这一节我们比较详细的讲述了在MVC中如何进行文件的上传,但是我们还有一点未曾讲到,则是利用流来将如我们上述的图片转换成字节来插入到数据库中。有关上传可以参考园友Insus.NET对此利用流来上传。

原文地址:https://www.cnblogs.com/CreateMyself/p/5414200.html

ASP.NET MVC 文件上传和文件下载 以及 文件下载的几种方法相关推荐

  1. asp.net mvc文件上传

    文件上传到文件夹下:  @using (Html.BeginForm("FileUp","Home",FormMethod.Post,new { enctype ...

  2. [转载]ASP.NET Core文件上传与下载(多种上传方式)

    ASP.NET Core文件上传与下载(多种上传方式) 前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在整理 ...

  3. ASP.NET Core文件上传IFormFile于Request.Body的羁绊

    前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式[1]中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题, ...

  4. spring mvc文件上传小例子

    spring mvc文件上传小例子 1.jsp页面 <%@page contentType="text/html;charset=UTF-8"%> <%@page ...

  5. ASP.NET中文件上传下载方法集合

    asp.net 2008-08-23 21:10:35 阅读0 评论0   字号:大中小 订阅 ASP.NET中文件上传下载方法集合 文件的上传下载是我们在实际项目开发过程中经常需要用到的技术,这里给 ...

  6. Spring MVC文件上传示例教程 - 单个和多个文件

    Spring MVC文件上传示例教程 - 单个和多个文件 文件上传是任何Web应用程序中非常常见的任务.我们之前已经看过如何在Servlet和Struts2文件上传中上传文件.今天我们将学习Sprin ...

  7. MVC文件上传07-使用客户端jQuery-File-Upload插件和服务端Backload组件裁剪上传图片...

    本篇通过在配置文件中设置,对上传图片修剪后保存到指定文件夹. 相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  MVC文件上传02-使用HttpPostedFileB ...

  8. 服务器 上传文件 杀毒,一种实现文件上传网站后自动进行杀毒的方法及系统

    1. 一种实现文件上传网站后自动进行杀毒的系统,其特征在于,包括: 服务器端监控模块,用于对每一个上传到服务器的文件进行监控: 服务器端的杀毒模块,用于对上传到服务器的文件进行病毒查杀: 位于服务器端 ...

  9. php104.tmp,ThinkPHP5.0多个文件上传后找不到临时文件的修改方法

    这是修改之前的代码 if(!empty($_FILES)){ if(!empty($_FILES[org_positive])){ $org_positive = request()->file ...

最新文章

  1. java学习笔记4--对象的初始化与回收
  2. Linux进程间通信——使用共享内存
  3. C/C++的64位整型
  4. LeetCode 334. 递增的三元子序列
  5. VUE项目中使用this.$forceUpdate()强制页面重新渲染
  6. 【Kafka】Kafka ArithmeticException: / by zer
  7. rhel 6.4 增加光盘为yum repo
  8. java 静态方法的使用_java的静态方法的使用
  9. (21)pandas.drop与dropna方法
  10. SVM多分类算法-一对一
  11. 解决win7 svchost占用CPU过高的问题
  12. 机房合作—SVN skipped remains conflicted
  13. ios13一直在估算剩余时间怎么办
  14. 【HTML】HTML网页设计-----游戏网页设计
  15. Unity特效基础:粒子效果面板
  16. 服务器运维KPI指标,IT运维包括哪些内容,考核标准是什么
  17. SQLConverter SQLserver数据库转换为SQLLite数据库
  18. 微信视频号怎么涨粉?我总结了5条经验_
  19. 吴师兄领证之前谈了多少个女朋友?
  20. 南开大学 软件学院 操作系统 李旭东老师 复习

热门文章

  1. SQL查找是否“存在“
  2. 贪心算法之——摘枇杷(nyoj680)(贪心+二分搜索)
  3. 3DMax—吹风机建模
  4. joomla joomla模板下载地址汇总
  5. unity重置天下霸图之进度汇总
  6. 暴雪和黑客的战争三:黑客的反击
  7. 轻松学c语言编程.pdf等,轻松学编程:轻松学C语言编程 PDF
  8. com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.
  9. UltraEdit文本编辑器丨功能介绍
  10. delmia机器人示教01