.net 下进行文件下载有两种模式,下面分类进行讲解
直接通过文件所在地址进行下载
这种方法最简单,直接通过访问文件所在的网址进行下载
1、在当前页面下载
<a href="/portal/dir/img/cusTemplate.xlsx">客户上传模板</a>
2、新开一个页面进行下载
<a href="/portal/dir/img/cusTemplate.xlsx" target="_blank">客户上传模板</a>
通过一个中转Url进行下载
1、建立一个文件下载公共类 FileHelper,用于统一下载
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
namespace PMS.Models
{
public class FileHelper
{
/// <summary>
/// 下载文件
/// </summary>
/// <param name="file_path">文件的fullpath</param>
/// <param name="show_name">下载文件的显示名称</param>
/// <param name="is_delete_localfile">文件下载后是否要进行删除</param>
public static void DownFile(string file_path, string show_name, bool is_delete_localfile)
{
//如果没有传入下载文件要显示的文件名,则自动用file_path中的文件名
if (string.IsNullOrEmpty(show_name))
{
show_name = Path.GetFileName(file_path);
}
//如果下载文件显示的名称已有当前后缀名,则不要重复添加
string ext = Path.GetExtension(file_path);
if (show_name.EndsWith(ext))
{
ext = "";
}
//文件名称进行编码,已防止中文乱码
show_name = HttpUtility.UrlEncode(show_name + ext, System.Text.Encoding.UTF8);
var response =System.Web.HttpContext.Current.Response;
response.Clear();
response.ClearHeaders();
response.AddHeader("Content-Transfer-Encoding", "binary");
response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", show_name));
response.WriteFile(file_path);
response.Flush();
if (is_delete_localfile)
{
File.Delete(file_path);
}
response.End();
}
}
}
2、建立一个Action进行下载
public ContentResult DownloadFile()
{
string file_path = Path.Combine(Server.MapPath("~/Content/Template"), "Tmpltemprice.xlsx");
FileHelper.DownFile(file_path, "批量模板.xlsx", false);
return Content("下载成功");
}
3、前端调用上面建立的Action进行下载
<a href="@Url.Action("DownActDemand", "UserCenter")" target="_blank">上传模板下载</a>
通过iframe + 中转Url进行异步下载
上面的下载方法是通过页面跳转的方法进行下载,如果当前页面中转失败的话会跳出错误页面,如果新页面跳转的话会出现空白等待,用户体验不好,这个可以通过iframe进行模拟新页面中转,这样就不会出现空白等待情况
但是如果网络出现异常、下载文件太大、等待时间太长,用户点击下载后页面就会出现没有反应的情况(***实际页面在下载***),导致用户以为程式异常了
为了解决以上的情况,我们可以在点击下载按钮的时候通过js显示一个loading遮罩层
便是这样又会出现一个问题,怎么判断文件下载完成了,iframe的load方法是在页面开始加载的时候触发的,文件小下载快的时候还可以进行,但是文件大下载慢的时候,load事件触发后关闭了loading遮罩层,但是文件还没有下载完成,用户还是会以为程式异常了
为了解决这个问题,再增加一个 js+cookies 处理方法,如下
1、修改公共类,增加接收前端传来的一个随机码,添加到cookie中
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
namespace PMS.Models
{
public class FileHelper
{
/// <summary>
/// 下载文件
/// </summary>
/// <param name="file_path">文件的fullpath</param>
/// <param name="show_name">下载文件的显示名称</param>
/// <param name="is_delete_localfile">文件下载后是否要进行删除</param>
/// <param name="compare_cookie_value">比较cookie值,进行异步下载控制loading层的隐藏</param>
public static void DownFile(string file_path, string show_name, bool is_delete_localfile, string compare_cookie_value)
{
//如果没有传入下载文件要显示的文件名,则自动用file_path中的文件名
if (string.IsNullOrEmpty(show_name))
{
show_name = Path.GetFileName(file_path);
}
//如果下载文件显示的名称已有当前后缀名,则不要重复添加
string ext = Path.GetExtension(file_path);
if (show_name.EndsWith(ext))
{
ext = "";
}
//文件名称进行编码,已防止中文乱码
show_name = HttpUtility.UrlEncode(show_name + ext, System.Text.Encoding.UTF8);
var response =System.Web.HttpContext.Current.Response;
response.Clear();
response.ClearHeaders();
response.AddHeader("Content-Transfer-Encoding", "binary");
response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", show_name));
/*cookie处理*/
HttpCookie cookie = new HttpCookie("CompareCookie");
cookie.Value = compare_cookie_value;
response.AppendCookie(cookie);
/*cookie处理*/
response.WriteFile(file_path);
response.Flush();
if (is_delete_localfile)
{
File.Delete(file_path);
}
response.End();
}
}
}
2、修改处理Action,接收一个cookie
public ContentResult DownloadFile(string compare_cookies)
{
string file_path = Path.Combine(Server.MapPath("~/Content/Template"), "Tmpltemprice.xlsx");
FileHelper.DownFile(file_path, "批量模板.xlsx", false, compare_cookies);
return Content("下载成功");
}
3、添加一个异步下载 文件的JS方法
function ajaxDownload(href) {
//显示下载等待遮罩层
showF1();
//生成一个随机处,作为一cookie值传入后台
var timeCookie = Math.random();
//把cookie值加入下载url后面
href = href + (href.indexOf('?') > -1 ? '&' : '?') + 'compare_cookies=' + timeCookie;
//建立一个iframe用于加载下载连接
var oldFrame = document.getElementById('downloadFrame');
if (oldFrame) {
document.body.removeChild(oldFrame);
}
var iframe = document.createElement('iframe');
iframe.id = 'downloadFrame';
iframe.style.display = 'none';;
iframe.href = href;
document.body.appendChild(iframe);
//每隔10秒获取后台返回的cookie进行比较,如果成功,则清除cookie,并结束此循环
window.downHandle = setInterval(function () {
var cookieValue = getCookie('CompareCookie');
if (cookieValue == timeCookie) {
closeF1();//关闭遮罩层
clearInterval(window.downHandle);//结束循环
}
}, 10);
}
给下载按钮添加click事件
$('#btnDownload').click(function () {
ajaxDownload('/UserCenter/DownloadFile');
});
以上就是下载的的大致方法了