最近在写一个Web版本的文件管理器,正好又有朋友问起web页面上面可以让图片也变成下载模式的那种链接方式在ASP.NET里面怎么实现,我给他写了一个大概,觉得也应该当作笔记贴出来,帮他写的时候,突然发现很多问题自己也不是明白,所以逐一查找了一番,贴出来和大家分享!
\n
应用场景,很多时候都有盗链等各种各样的原因,用ASP.NET呢,最基本的一个问题,我的所有数据文件都保存在App_Data,这个文件夹和配置文件Web.Config一样,直接是无法访问其中内容的,所以如果里面上传了文件,无论是图片,还是压缩包,想下载就要通过某个点Response.WriteFile出去,不过在讨论的时候又发现了一些新的内容,如下:
\n
首先,是下载的基础,Http Header 的做两个设置:
\n
- Content-Type : (这个~很无语的东西,每次都记不住,现查!Wiki)
application/octet-stream 万金油型,什么文件都适合!
application/x-zip-compressed 专门针对Zip文件的,但是在某些情况下有奇效,这个后面讲
\n - Content-Disposition : 此属性设置内容输出的方式和属性,不大会使,常用就两种操作方式,一个是inline,另一个就是attachment;在输出类型之后可以跟着一些参数,在操作下载的时候如果我们不希望我们输出的文件编程abc.aspx的名字,就要设置filename的参数项,其他的参数项有:creation-date,modification-date,read-date,size。这些内容在后面讲高级的下载输出时会用得到哦。
\n
\n
只要对上述的两个设置项进行设置以后就可以正常输出问题了,还需要服务器段的代码,以下我列出了三个实现,第一个是最简单的原型,然后再它的基础上有一个备选,最后一个是一个来自MSDN的高级解决方案,没研究明白到底是否该用~
\n
最简单的实现:
新建一个WebForm页面,然后在Page_load里面添加内容:
\n
protected void Page_Load(object sender, EventArgs e)\n
\n{
\nif (null != Request.QueryString["key"])
\n{
\nstring path = Request.PhysicalApplicationPath + @”App_Data\\”
\n+ Request.QueryString["key"].Replace(‘/’, Path.DirectorySeparatorChar);
\nif (File.Exists(path))
\n{
\nFileInfo fi = new FileInfo(path);
\nResponse.Clear();
\nResponse.ContentType = “application/octet-stream”;
\n// 注意!这个地方一定要用AppendHeader。MSDN上很多地方指导使用
\n// Response.Headers.Add 或 Response.AddHeader
\n// 但是在MSDN中明确写出,这些都是为了兼容ASP,在.NET 3.5要求使用下面这种方式。
\n// 如果使用了上述两种方式可能会产生“此操作要求使用 IIS 集成管线模式。 ”的异常。
\nResponse.AppendHeader(“Content-Disposition”, string.Format
\n(“attachment;filename=\\”{0}\\”",HttpUtility
\n .UrlEncode(fi.Name, System.Text.Encoding.UTF8)));
\nResponse.AppendHeader(“Content-Length”, fi.Length.ToString());
\nResponse.WriteFile(fi.FullName);
\n}
\nelse
\nResponse.Write(string.Format(“access is error.{0} is no exist.”, path));
\n}
\nelse
\n{
\nResponse.Write(“i need key!”);
\n}
\n}