ASP.NET MVC 向浏览器发送文件以提供文件下载功能

     撑到大三了,结果发现周围的同窗更加堕落了,尤为是某些人,表面上看起来很认真,实际上三天打鱼,两天晒网,结果一事无成,却还要抱怨学校教育失败。数组

     为了吸收他们的教训,就算是一个小小的编码问题,我也要努力解决。由于学习的机会一贯都在,只是本身有没有去努力而已。浏览器

     以前作个班级站点的课程设计,用一天半的时间作完虽然各方面不咋样,但麻雀虽小,五脏俱在,功能流程仍是挺完整的。服务器

     就算是一个小小的课程设计,在这短暂的时间内,也遇到了很多问题,有大有小。app

     先说文件下载这块。学习

     文件下载通常都是须要一个文件选择对话框来选择存放文件的地方。咱们能够本身作一个,但简单的方面就是利用浏览器的现成功能。编码

     全部的浏览器都包括文件下载功能,但文件选择对话框却不是每一个浏览器都有提供。这里我只选择我经常使用的两个浏览器:谷歌浏览器和搜狗浏览器。spa

     先来一个小例子:设计

public ActionResult Index()
{
     var path = Server.MapPath("~/frog.jpg.jpg");
     return File(path, "iamge/jpeg");
}

     这里是下载工程根目录下的frog.jpg.jpg。
     代码很是简短,只有两行,但效果却不差:3d

      

      这是搜狗浏览器上的效果,若是是谷歌浏览器,则是直接下载下来,可是文件并非咱们的文件名,甚至格式也不同,就是一个奇怪的名为"下载"的文件。code

      首先是解释上面两行代码的原理:

      Server.MapPath()的参数是一个虚拟路径的,它的原理是根据提供的虚拟路径返回一个虚拟路径对应的物理路径,并且参数路径必须是虚拟路径。咱们服务器上传的文件都是放在服务器的一个路径下,这个路径是物理路径,可是打开文件的URL倒是虚拟路径,这样的好处就像是相对路径和绝对路径的对比,想一想若是咱们将文件的额存放地点放在另外一个地方,若是URL为物理路径,那么就会找不到该文件。

      path如今是frog.jpg.jpg的物理路径,而后咱们要将该文件发送给浏览器,则须要利用FilePathResult的File(),指定发送文件的物理路径和格式就能够了。

      值得注意的是,若是是在搜狗中,指定格式是application/x-zip-compressed(zip的MIME格式)或者application/octet-stream(rar的MIME格式),在网页上看到的将会是乱码,但若是是谷歌,依然是上面那样的状况,可是用压缩文件软件打开,就会发现里面就是咱们要的文件,它确实是被下载下来了。

      因为谷歌浏览器的行为与咱们想要的效果差了太远了,因此下面就再也不讨论谷歌浏览器的行为。

      我用word文档,Excel表格和txt文档格式的文件分别发送给浏览器,结果只有txt文档的文件中的内容可以正常显示在网页中,其余都是乱码,可见,网页可以直接打开的文件格式是有限的,至少须要第三方软件打开的文件是没法打开的。

      上面这些都不是重点,只是个人一点好奇心而已。如今咱们进入重点,就是让浏览器提供下载对话框。

      要实现这样的功能,上面的代码是不行的,至少我这边是不行的,要用下面的代码: 

var path = Server.MapPath("~/1.txt");
var name = Path.GetFileName(path);
return File(path, "application/zip-x-compressed", name);

      而后浏览器的运行效果如:

  

     这就是咱们想要的结果。

     咱们增长了一行代码,就是使用Path.GetFileName()来获取指定物理路径的文件的文件名和扩展名,而后再在File()中增长一个新的参数,该参数就是咱们要下载的文件的文件名和扩展名。

      但可怕的是,上面代码中File的格式能够随便指定,甚至能够直接为"1"(只要不是null以及""),都会提供上面的下载对话框!!这告诉咱们,该下载对话框须要的并非文件的正确格式,它须要的仅仅只是须要下载的文件的文件名(这个文件名并必定要是正确的文件名,咱们能够指定新的名字,反正它就只要将该物理路径下的那个文件下载下来就行)以及该文件的物理路径。

   必须注意的是,若是文件名包含有中文,那么它就会显示这样的效果:

        若是想要显示正确的中文文件名,咱们能够这样作:

return File(path, "1", Url.Encode(name));

        效果就会这样:

       

   要实现上面的效果,咱们还能够这样作:
byte[] data = Encoding.UTF8.GetBytes("~/中国.txt");
return File(data, "1", Url.Encode("中国.txt"));

      这里咱们是直接将"~/中国.txt"变为byte[]数组而后发给浏览器,保存在中国.txt中,打开就是"~/中国.txt"。这种方式属于FileContentResult。

      大概的内容就是上面这样,固然咱们能够自定义,毕竟像是谷歌浏览器根本就不提供下载对话框的状况下,更加须要咱们自定义下载对话框,但这里不讲,先是这样,之后再继续补充。

相关文章
相关标签/搜索