又是网站的功能,先稍稍抱怨下,以前打算专门去做网站的,结果工作后几乎没再碰过。这次有一个平台,由于客户不满意,要求增加功能,结果被临时拉过来。真是苦命啊,还好之前学校有一些开发经验。
老大是让我完成文件上传、维护、下载,其实我当时并没有把下载这块功能放在心上。虽然以前没有这方面开发的经验,但也记得直接写一个链接<a href="url"/>就可以下载了。而且也这么实现了。然而需求总是在变,还有那测试部也会提一些意见。
首先大体说下文件上传和维护。我把上传是文件放在一个文件夹中,然后建一个mysql表,对这些文件进行分类很管理。
然而如上面所说的,会出现一种情况,如果有人上你发布网站的服务器,直接将文件删除了,其实我个人觉得不太可能,但测试部提出来了,好吧,我乖乖的改下。于是,相当于是扩展了功能,我使用JQuery的$.Ajax来把文件名和文件地址传给一个页面,然后判断该文件是否存在,存在才进行下一步操作,不存在就不下载。这边有个很有趣的事情,那就是相对于$.Ajax。下面带些代码:
“<span style="color:red"><a href="' + rowData.ResourceUrl + rowData.ID + '" οnclick="return ExistFile(this)">下载</a></span>”。
上面那段代码,我是动态生成的。执行一个onclick事件,而且我是始终返回false。ExistFile(this)的代码:
function ExistFile(Obj) {
var href = $(Obj).attr("href");
var str = "url=" + href;
var strtxt = "strFilePath=" + encodeURI(href);
$.ajax({
type: "get",
url: "../../Ajax/AjaxOperation.aspx?timestamp=" + new Date().getDate(),
data: "Type=ExistFile&" + strtxt,
async: false,
success: function (msg) {
if (msg == "1") {
$.messager.alert("系统提示", "资源不存在,或已被删除");
} else {
window.location.href = "../UploadResource/DownLoadResource.aspx?" + str;
}
}
});
return false;
}
方法始终返回false,然后根据文件是否存在来判断是提示,还是下载(其中”1“是由AjaxOperation.aspx页面返回的)。上面那段是最终的代码,其实一开始我是使用window.location.href =”文件地址“,就直接下载。而且不能放在$.Ajax方法外面,个人感觉是异步,大家可以试试,在return false前面加个消息框,和在success里面的方法也加个消息框,结果第一个消息框先弹出来。本来我是打算定义一个bool型变量,然后文件存在放回true,不存在返回false,这样子,看来是不行了,设置成同步也不行。
但这样,又出现一些问题,那便是txt文件还有一些图片格式,不能下载,变成打开。功能实现到这里,我郁闷了,于是我用一个很无耻的方法,在上传的时候,限制格式,碰到txt或图片,要求压缩后上传。
事情到这里,个人感觉是完工了,交差,而且测试部还有老大也没有提更新。但过了俩天,也就是昨天晚上,突然感觉,这样做有点问题,不能让客户来满足我们自己的要求,而是应该我们去尽量为客户的着想,于是便上网瞅瞅。这一瞅,我更郁闷了,原来网上这么多方法。。。
而要实现下载txt还有一些带特殊字符的,比如”#%“之类的文件名,就得通过window.location.href = "../UploadResource/DownLoadResource.aspx?" + str;,把跟文件有关的,比如文件路径之类的,传给DownLoadResource.aspx页面,然后在改页面调用的C#代码里面的Page_Load实现下载,代码:
protected void Page_Load(object sender, EventArgs e)
{
string url=Request.QueryString["url"];
DownLoad(url);
}
ResourceServiceLocalBussinessImplement implement = new ResourceServiceLocalBussinessImplement();
public void DownLoad(string filepath) {
string destFileName = string.Empty;
string[] strarray=filepath.Split('/');
string filename = implement.GetModel(strarray[strarray.Length - 1]).ResourceName;
filepath = strarray[strarray.Length - 2] + "/" + filename;
destFileName = Server.MapPath("~") + filepath;
//destFileName = Server.UrlDecode(destFileName);
if (File.Exists(destFileName))
{
FileInfo fi = new FileInfo(destFileName);
Response.Clear();
Response.ClearHeaders();
Response.Buffer = false;
Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(destFileName), System.Text.Encoding.UTF8));
Response.AppendHeader("Content-Length", fi.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(destFileName);
Response.Flush();
Response.End();
}
}
这里就不注释了,要是想了解下,自己拷下代码,然后把鼠标放上去,就能看Response调用的各个方法的注释。
这边我还是传的是href,但是href最后面不是传文件名,因为文件名可能有特殊字符”#%“等,如果带这些字符,会被截断,不行自己去试下,试下才能映像深刻。我传的是id,mysql数据表中的主键,然后通过主键再去数据库中获取文件名,也许多此一举吧,但至少解决掉特殊字符,你爱咋传咋上传。
这里实现这些功能有些东拼西凑,js和Jquery混着用。主要是记录下自己的遇到的情况,和实现的思路。