与ASP.NET其它所有控件一样,文件上传的实现同样有两种方式,一种是用服务端控件,另一种是利用客户端表单+.ashx的方式,当然,用Ajax完成文件上传也行,原理与客户端表单+.ashx的方式类似,只是传统的jQuery或javascript不支持Ajax提交文件,因此在前端可能你要借助Uploadify等控件才行。
如下图所示:
用两个形式,实现一个基本的pdf文件上传系统,当然这个文件上传系统还并不那么完善。实际上,文件上传系统还要进一步加工,考虑到大文件如果分割的情况,不要一次性将几M,十几M,几十M的东西往服务器那里扔。
解决方案目录结构如下:
由于Asp.net默认规定的上传文件大小仅有4M,因此,做这个系统你必须先在Web.Config修改一些东西,否则,上传大于4M的东西,解决方案会报错,直接找不到页面的。
具体是在system.web这一节加上如下语句:
<httpRuntime maxRequestLength="40960" executionTimeout="6000"/>
修改最大的上传大小为40M,处理一个文件最大时间为6s。
这样一定提高文件的上限。根据需要还可以进一步修改,当然上传更大的文件,你应该考虑使用一个文件上传插件,将大文件分割成一块又一块上传,实现断点上传等等。
毕竟,用户要上传一个30M的文件,将会在服务端中申请30M的内存去处理这个东西的,一些小型服务器吃不消。
在主页面Default.aspx的布置很简单:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FileUpload._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> ASP.NET服务端控件的形式: <form id="form1" runat="server"> <asp:FileUpload runat="server" ID="FileUpload1" /> <asp:Button runat="server" ID="Button1" OnClick="Button1_Click" Text="上传" /> </form> 客户端控件的形式: <form action="FileUpload.ashx" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="submit" value="上传" /> </form> </body> </html>
服务端表单,则直接使用ASP.NET封装好的FileUpload控件。需要注意的是,所有ASP.NET服务端控件都必须加上runat="server"。
先说对服务端控件搞上来的文件处理的Default.aspx.cs:
1、文件上传到解决方案根目录下的Upload文件夹之中。根目录可以通过Server.MapPath("~/")来获取。
2、此处服务端的文件名组织,写成原文件名+下划线+时间戳的形式,实际运用中还仅仅用时间戳、随机数来存这个文件,其它与这个文件相关信息存到数据库中,这样给用户下载的url可以简单很多,当然如果不提供下载、不打算入库,就还可以在文件名中带上用户id直接的,文件名请根据实际运用需要来组织。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace FileUpload { public partial class _Default : System.Web.UI.Page { /// <summary> /// 获取时间戳 /// </summary> public static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } protected void Page_Load(object sender, EventArgs e) { if (Session["info"] != null)//处理FileUpload.ashx传过来的信息 { Response.Write(Session["info"]); Session.Remove("info");//用完就销毁,减轻服务器的负担,相当于jsp的request容器 } } protected void Button1_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { string fileName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.LastIndexOf("."));//文件名 string suffix = FileUpload1.FileName.Substring(FileUpload1.FileName.LastIndexOf(".")).ToLower();//后缀名 if (suffix.Equals(".pdf")) { FileUpload1.PostedFile.SaveAs(Server.MapPath("~/") + "./Upload/" + fileName + "_" + GetTimeStamp() + suffix); Response.Write("上传成功!"); } else { Response.Write("请上传pdf文件!"); } } else { Response.Write("请选择文件!"); } } } }
1、上传的文件,可以通过HttpPostedFile file = context.Request.Files["file"];来获取,通过file.ContentLength > 0来判断其是否有文件上传。
2、需要注意到的还是.ashx中编程与.aspx.cs一些不同的地方,例如Session的使用需要自己调用接口。Respond与Request不能直接使用,需要用到context。Server同样不能直接使用,需要通过HttpContext.Current.Server来使用。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState;//要在ashx文件中使用Session就必须加这个 namespace FileUpload { /// <summary> /// FileUpload 的摘要说明 /// </summary> public class FileUpload : IHttpHandler, IRequiresSessionState//要在ashx文件中使用session就必须调用这个接口 { /// <summary> /// 获取时间戳 /// </summary> public static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; HttpPostedFile file = context.Request.Files["file"]; if (file.ContentLength > 0) { string fileName = file.FileName.Substring(0, file.FileName.LastIndexOf(".")); string suffix = file.FileName.Substring(file.FileName.LastIndexOf(".")).ToLower(); if (suffix.Equals(".pdf")) { file.SaveAs(HttpContext.Current.Server.MapPath("~/") + "./Upload/" + fileName + "_" + GetTimeStamp() + suffix); context.Session["info"] = "上传成功!"; } else { context.Session["info"] = "请上传pdf文件!"; } } else { context.Session["info"] = "请选择文件!"; } context.Response.Redirect("Default.aspx"); } public bool IsReusable { get { return false; } } } }