最近在项目中碰到了多文件上传,用的是Jquery插件:Jquery.MultiFile.js,官网:http://www.fyneworks.com/jquery/multiple-file-upload/ ,由于在同一个页面中用到了UpdatePannel,有用到了Jquery插件,这两个混合用造成了多文件上传插件失效,在网上搜索了一些结果,最终知道原因问题总算搞定;
今天做一个模拟环境来记录下:
前台页面代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_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"> <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> <script src="Scripts/jquery.MultiFile.js" type="text/javascript"></script> <title></title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function EndRequestHandler(sender, args) { $('#attFile').MultiFile({ list: '#att-list' }); } </script> <div> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <Triggers> <asp:AsyncPostBackTrigger ControlID="btnAsyn" EventName="Click" /> <asp:PostBackTrigger ControlID="btnSyn" /> </Triggers> <ContentTemplate> <input type="file" id="attFile" name="attFile" style="border: thin solid #C0c0c0; margin: 1px 1px 1px 1px" accept="xls|xlsx|docx|doc|ppt|pptx|pdf|txt|gif|bmp|jpg|zip|avi|wmv" class="multi" /> <div id="att-list"> </div> <asp:Button ID="btnAsyn" runat="server" Text="Asynchronous" OnClick="btnAsyn_Click" />//用来模拟会发操作 <asp:Button ID="btnSyn" runat="server" Text="Synchronous" OnClick="btnSyn_Click" />//在UpdatePannel内部用按钮提交表单 </ContentTemplate> </asp:UpdatePanel> <asp:Button ID="btnUploadFile" runat="server" Text="Button" OnClick="btnUploadFile_Click" />//在UpdatePannel外部用按钮提交表单 </div> </form> </body> </html>
后台代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.IO; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.Form.Enctype = "multipart/form-data"; } } /// <summary> /// get current HttpContext all files /// </summary> /// <returns></returns> private List<string> GetAttachement()//用来得到文件 { System.Web.HttpFileCollection files = System.Web.HttpContext.Current.Request.Files; if (files != null && files.Count > 0) { try { string filePath = "~/UploadFiles"; string phyPath = HttpContext.Current.Request.MapPath(filePath); if (!Directory.Exists(phyPath)) { Directory.CreateDirectory(phyPath);//.Create(); } List<string> fileNameString = new List<string>(); for (int index = 0; index < files.Count; index++) { System.Web.HttpPostedFile postedFile = files[index]; string fileName = System.IO.Path.GetFileName(postedFile.FileName); if (!String.IsNullOrEmpty(fileName)) { string fileExtension = System.IO.Path.GetExtension(fileName); DateTime now = DateTime.Now; string strFileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(fileName); string saveName = strFileNameWithoutExtension + "_" + now.ToString("yyyyMMddHHmmss") + fileExtension; postedFile.SaveAs(string.Format("{0}\\{1}", phyPath, saveName)); fileNameString.Add(saveName); } } return fileNameString; } catch { return null; } } else return null; } protected void btnUploadFile_Click(object sender, EventArgs e) { List<string> files = GetAttachement(); if (files!=null && files.Count>0)//在UpdatePannel外部提交后查看得到的文件个数 { } } protected void btnAsyn_Click(object sender, EventArgs e) { } protected void btnSyn_Click(object sender, EventArgs e) { List<string> files = GetAttachement(); if (files != null && files.Count > 0)//在UpdatePannel内部提交后,调试查看得到的文件个数 { } } }
初始化运行界面:
选择两个文件:
这个时候提交表单查看获得的文件个数:
一共添加了两个文件,获得的文件个数是2
问题1:这个时候模拟一次异步回传后在添加文件:单击异步回传按钮,再进行添加文件,Jquery插件就会失效,不能添加文件,
失效后的截图:
插件失效解决方案:
<body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <script type="text/javascript" language="javascript"> Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);//用这句话就能解决问题。详细解释请查看微软官网:http://msdn.microsoft.com/en-us/library/bb383810(v=vs.100).aspx function EndRequestHandler(sender, args) { $('#attFile').MultiFile({// list: '#att-list' }); } </script>
添加以上脚本Jquery.MultiFile.js有能正常工作。
问题2:通过UpdatePannel外部的按钮提交获得文件没有任何问题,但是当通过UpdaePannel内部的按钮提交表单,总是获得不到文件个数:
问题截图如下:
问题2解决方案:设置UpdatePannel内部的按钮为回传性质的按钮,代码如下:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <Triggers> <asp:AsyncPostBackTrigger ControlID="btnAsyn" EventName="Click" /> <asp:PostBackTrigger ControlID="btnSyn" />//一定要加上这句话,给按钮设置回传属性 </Triggers>
最后好药注意一点,非常重要,是上传文件比不可少的:
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { this.Form.Enctype = "multipart/form-data";//在这里设置或者直接在表单属性设置:<form id="form1" runat="server" enctype="multipart/form-data"> } }