添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

2、结果展示

2.1、上传文件成功界面

2.2、下载文件成功界面

3、上传文件代码

3.1、View代码

@* 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 " /> <input type= " submit " name= " Upload " value= " Upload " /> // 保存成自己的文件全路径,newfile就是你上传后保存的文件, // 服务器上的UpLoadFile文件夹必须有读写权限 string target = Server.MapPath( " / " )+( " /Mock/Learning/ " ); // 取得目标文件夹的路径 string filename = file.FileName; // 取得文件名字 string path = target + filename; // 获取存储的目标地址 file.SaveAs(path);} return View();

4.1、View代码

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

4.2、Controller代码

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

前提: 要下载的文件必须是在服务器目录中的,至于不在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

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

(3)TransmitFile方法

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(); 3 string fileName = "aaa.txt";//客户端保存的文件名 4 string filePath = Server.MapPath("~/Document/123.txt");//路径 6 System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath); 7 if (fileInfo.Exists == true) 9 const long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力 10 byte[] buffer = new byte[ChunkSize]; 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 }

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

success: function (result) { window.location.target
= "_blank"; window.location.href = result; 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类:

[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;
                return true;

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

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

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

var fileName = bModel.BlogPhoto.FileName; var filePath = Server.MapPath(string.Format("~/{0}", "File")); bModel.BlogPhoto.SaveAs(Path.Combine(filePath, fileName)); ModelState.Clear(); return View();

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

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

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

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

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

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

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

</style> <form id="uploadFileSub" action="/Home/UploadFile" method="post" enctype="multipart/form-data"> <fieldset> <legend></legend> <ul class="lifile"> @Html.LabelFor(m => m.BlogName)
<br /> @Html.TextBoxFor(m => m.BlogName, new { maxlength = 50 }) @Html.ValidationMessageFor(m => m.BlogName) @Html.LabelFor(m => m.BlogAddress)<br /> @Html.TextBoxFor(m => m.BlogAddress, new { maxlength = 200 }) @Html.ValidationMessageFor(m => m.BlogAddress)<br /> @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> <input type="submit" value="提交" /> </fieldset> </form>
    function GetFileSize(fileid) {
        var fileSize = 0;
        fileSize = $("#" + fileid)[0].files[0].size;
        fileSize = fileSize / 1048576;
        return fileSize;
 
    function getNameFromPath(strFilepath) {
        var objRE = new RegExp(/([^\/\\]+)$/);
        var strName = objRE.exec(strFilepath);
        if (strName == null) {
            return null;
        else {
            return strName[0];
 
        $("#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;
 
        $("#uploadFileSub").submit(function () {
            $("input[type='text']").each(function (k, v) {
                if ($(v).length) {
                    $(v).siblings("span").hide();
            if (fileTypeBool || fileSizeBool) {
                return false;
 
@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时,以为所有文件都需要走一遍路由,然后才能在客户端显示,所以我首先介绍这一种方式比如说:我们在服务器上有图片: ~/resource/image/5.jpg我们就需要在控制器下新写:(旨在当浏览器发出请求时,服务器内存读取图片文件,以图片流的方式传给浏览器)public ActionResult GetImg(){string strPath = Server.Map... 解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹/// 被压缩的文件名称(包含文件路径)/// 压缩后的文件名称(包含文件路径) 网上有各种各样的说法和办法,但都不好用,或没有说到关键的地方。 还有的建议传字符串后台格式化或解析,也有专门写一个切面程序修改mvc自带的格式化方法的,等等,都不是想要的东东。 我需要的是一个简简单单,不做任何改动就能实现的方法。 今天遇到这个问题,反复调试了好多次,终于找到了最简单的方法,什么都... 本例旨在说明我的一种Controller接收ajax提交(POST)过来的json对象或数组信息的方式,感觉应该有更好的方式,欢迎提出宝贵意见。JSON.stringify(jsonObj)不支持IE8以下浏览器  前端页面代码如下: 在网站开发中我们经常需要用到表单,那么,在前台页面的表单中提交到后台控制器后,后台控制器就要接收表单提交过来的数据,然后实现新增功能 我们可以先写一个HTML的前端页面的表单来作为前台页面。 大致是要新建一个MVC项目,然后添加一个控制器,;在控制器的默认方法index中, 代码如下,新增功能的实现: 先看控制器的代码 在点击Create.aspx页面中的 Create 按钮时执行上面这段代码,如果新增信息成功则打开Index.aspx页面,如果失败则打开Create.aspx页面进行重新输入 [HttpPost("Upload")] [RequestSizeLimit(1024 * 10240)] public string Upload(List<IFormFile> files) NLogHelper.Info("====SavePicture==="); var url="http://xxxxxx.com/abc.pdf"; System.Net.WebRequest myRequest = System.Net.WebRequest.Create(url); System.Net.WebResponse myResponse = myRequest.GetResponse(); var file=myResponse.GetResponseStream();. 我已经在运行.net MVC应用程序的Web服务器上设置了到另一台用于存储上载文件的服务器的网络路径。为了允许通过应用程序将文件上传到网络路径,我修改了IIS中的应用程序池,以便该应用程序有权上传到它。这一切都很好。为了使应用程序在加载页面时能够读取文件,我在IIS中创建了一个虚拟目录,该目录现在作为IIS中该站点的文件系统的一部分出现。然后,如何在我的应用程序中访问并为此位置生成路径,以便可以将... &lt;form action='@Url.Action("Upload", "File")' method="post" enctype="multipart/form-data"&gt; &lt;input type="file" name="file" /&gt; asp.net里提供了多种方式,从服务器端向客户端写文件流,实现客户端下载文件。这种技术在做防下载系统时比较有用处。其中WriteFilet和BinaryWrite出现得比较早,对文件流的输出可以启动作用,但由于都是将整个文件读到内存后再往客户端写,因此会占用大量的内存资源,特别是要下载文件比较大时,影响asp.net应用的稳定运行。 今天因为工作需要,写一个Excel上传下载的.Net MVC工程的Demo。因为自己是个新手,再编写的过程中百度无数次,遇到很多低级错误。最终完成后,发现在.Net MVC中实现文件上传下载都非常简单。 首先,在VS中创建一个.Net MVC工程,工程中默认带有了一套MVC的样例代码。因为只是写Demo,我就直接在这个基础上进行了小改动以实现自己需要的效果。