最近做的一个高校网站中涉及到了上传和下载文件的需求(具体需求为:网站公布的通知,在后台要能给每个通知添加附件,在前台要能显示并下载附件),之前只是学习过关于上传的理论,这里探索了一下下,与大家分享一下成果。
事先说明:这个例子采用的是简单的三层结构,层与层之间是用实体来传值。而且这种方法不但在本地测试时可以成功,并且可以部署在服务器上,供异地上传和下载文件。
专门做了一个数据库表用来存储附件的相关信息:
字段 | 说明 |
AnnexID | 附件ID |
AnnexName | 附件名称 |
AnnexAddress | 存储附件的地址 |
NoticeID | 附件所属“通知”的ID |
ASP.NET实现上传文件
前端
界面十分简单,只是放一个file类型的<input>和一个按钮,并且为这个按钮添加点击事件(btnUpLoad_Click),如下图:
代码:
<input id="UpLoad" type="file" runat="server" /> <asp:Button runat="server" Text="上传" ID="btnUpLoad" OnClick="btnUpLoad_Click" />
后台
再就是在后台编写上传按钮点击事件UpLoad_Click里的代码,先大体说一下思路:
1、根据file类型的<input>控件获得将要上传文件在本机的物理路径;
2、在这个物理路径中用截取字符串的方法获得文件名(第一步中取得的路径为本机的绝对路径,在服务器上是无效的,所以这里我们只需要获取文件名);
3、利用file类型的<input>控件属性PostedFile的SaveAs()方法将相应文件存储到服务器中指定的文件夹中。
核心代码:
protected void btnUpLoad_Click(object sender, EventArgs e) { //取出所选文件的本地路径 string fullFileName = this.UpLoad.PostedFile.FileName; //从路径中截取出文件名 string fileName = fullFileName.Substring(fullFileName.LastIndexOf("\\") + 1); //限定上传文件的格式 string type = fullFileName.Substring(fullFileName.LastIndexOf(".") + 1); if (type == "doc" || type == "docx" || type == "xls" || type == "xlsx" || type == "ppt" || type == "pptx" || type == "pdf" || type == "jpg" || type == "bmp" || type == "gif" || type == "png" || type == "txt" || type == "zip" || type == "rar") { //将文件保存在服务器中根目录下的files文件夹中 string saveFileName = Server.MapPath("/files") + "\\" + fileName; UpLoad.PostedFile.SaveAs(saveFileName); Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('文件上传成功!');</script>"); //向数据库中存储相应通知的附件的目录 BLL.news.InsertAnnexBLL insertAnnex = new BLL.news.InsertAnnexBLL(); AnnexEntity annex=new AnnexEntity(); //创建附件的实体 annex.AnnexName=fileName; //附件名 annex.AnnexContent=saveFileName; //附件的存储路径 annex.NoticeId = noticeId; //附件所属“通知”的ID在这里为已知 insertAnnex.InsertAnnex(annex); //将实体存入数据库(其实就是讲实体的这些属性insert到数据库中的过程,具体BLL层和DAL层的代码这里不再多说) } else { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('请选择正确的格式');</script>"); } }
ASP.NET实现下载文件
上述操作已经可以实现将一个个控件存入数据库,在数据库中存储的情况给大家截了个图:
下面就要把这些控件在页面上显示,页面显示效果为:
点击附件,浏览器提示下载:
前台:
按照需求来说,每则发布的通知可以包含若干个附件,所一前台用了repeter控件来显示多个附件:
代码:
<asp:Repeater ID="rptAnnex" runat="server"> <ItemTemplate> <%--为repeter添加序号--%> 附件:<%#Container.ItemIndex + 1 %> <asp:LinkButton ID="lbtnDownLoad" runat="server" OnCommand="lbtnDownLoad_Command" CommandArgument="<%#((Model.AnnexEntity)Container.DataItem).AnnexContent %>"><%#((Model.AnnexEntity)Container.DataItem).AnnexName %></asp:LinkButton> <br /> </ItemTemplate> </asp:Repeater>
后台
ASP.NET可以采用多种方式下载文件(详情可参考《ASP.NET下载文件的几种方式》),这里采用了流式的下载方式(参考文章《Asp.net下载实例》):
using System.IO; protected void lbtnDownLoad_Command(object sender, CommandEventArgs e) { // 定义文件名 string fileName = ""; // 获取文件在服务器的地址 string url = e.CommandArgument.ToString(); // 判断传输地址是否为空 if (url == "") { // 提示“该文件暂不提供下载” Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script defer>alert('该文件暂不提供下载!');</script>"); return; } // 判断获取的是否为地址,而非文件名 if (url.IndexOf("\\") > -1) { // 获取文件名 fileName = url.Substring(url.LastIndexOf("\\") + 1); } else { // url为文件名时,直接获取文件名 fileName = url; } // 以字符流的方式下载文件 FileStream fileStream = new FileStream(@url, FileMode.Open); byte[] bytes = new byte[(int)fileStream.Length]; fileStream.Read(bytes, 0, bytes.Length); fileStream.Close(); Response.ContentType = "application/octet-stream"; // 通知浏览器下载 Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); }
到这里就大功告成了,欢迎分享更好的方法!
时间: 2024-11-05 16:36:11