当前位置:   article > 正文

C#结合JavaScript实现多文件上传_c#js上传文件

c#js上传文件

目录

需求

引入

关键代码

操作界面

JavaScript包程序

服务端 ashx 程序

服务端上传后处理程序

小结


需求

在许多应用场景里,多文件上传是一项比较实用的功能。实际应用中,多文件上传可以考虑如下需求:

1、对上传文件的类型、大小有一个基本的控制。

2、上传文件时有一个进度显示,包括当前文件和整体进度。

3、上传后,在服务端后续事件进行一些处理。

引入

首先请在WEB应用程序根目录下创建COMMON目录,并引入 JavaScript 程序包,该程序包已经打包,下载地址为:https://download.csdn.net/download/michaelline/88615565

下载成功后解压到COMMON目录即可,请引入如下图中的 JS 文件:

另外,我们还需要在 app_data目录下创建 ajaxUploadFiles 子目录,以备上传创建文件使用。

关键代码

操作界面

界面上放置标准的 input file 控件,并将其服务器化,即 runat="server"。点击选择文件,选中所有目标文件后,自动实现文件上传功能。

示例界面如下:

示例UI代码如下:

  1. <input class="file" type="file" id="ajaxMfile" runat="server"
  2. onbeginupload="ajax_uploadFiles_beginUpload" onprogressupload="ajax_uploadFiles_progressUpload" onendupload="ajax_uploadFiles_endUpload"
  3. multiple="multiple" allowtype="pptx|docx|mp3|txt|std" allowsize="500m|100m" fileindex="0" name="fileupload"
  4. serverbuttonid="ajaxEndBtn" serverfilelistid="ajaxReturnFileName"
  5. progresspanelid="ajaxMfileProgressPanel"
  6. onchange="ajax_uploadFiles(this);return false" />
  7. <asp:TextBox runat="server" Width="100%" ID="ajaxReturnFileName" style="display:none" ></asp:TextBox>
  8. <br />
  9. <asp:button ID="ajaxEndBtn" text="后台处理" runat="server" style="display:none" onclick="ajaxEndBtn_Click" />
  10. <br />
  11. <br />
  12. <table style="display:none; color:White" id="ajaxMfileProgressPanel">
  13. <tr>
  14. <td >
  15. 当前文件:</td>
  16. <td style="position:relative; padding:0px">
  17. <asp:Label Font-Size="9pt" style="z-index:1;position:absolute;left:0px;top:-9px;" Width="300px" runat="server" ID="ajax_uploadFiles_curfilename"/>
  18. </td>
  19. </tr>
  20. <tr>
  21. <td style="position:relative; padding:0px;width:120px">
  22. 当前文件进度<asp:Label style="z-index:1;position:absolute;left:85px;top:-9px;" runat="server" Font-Size="9pt" ID="ajax_uploadFiles_upprogress"></asp:Label>
  23. </td>
  24. <td style="position:relative; padding:10px">
  25. <img id="ajax_uploadFiles_curprogress" style="z-index:1;position:absolute;left:0px;top:4px;width:0px;height:12px" alt="" src="/common/Jquery/images/win7progress.jpg" />
  26. <div id="ajax_uploadFiles_curbg" style="z-index:0;position:absolute;left:0px;top:4px;width:300px;height:12px;background-color:Gray"></div>
  27. </td>
  28. </tr>
  29. <tr>
  30. <td style="position:relative; padding:0px">
  31. 上传总量进度<asp:Label style="z-index:1;position:absolute;left:85px;top:-9px;" runat="server" Font-Size="9pt" ID="ajax_uploadFiles_cprogress"></asp:Label></td>
  32. <td style="position:relative; padding:10px">
  33. <img id="ajax_uploadFiles_totalprogress" style="z-index:1;position:absolute;left:0px;top:4px;width:0px;height:12px" alt="" src="/common/Jquery/images/win7progress2.jpg" />
  34. <div id="ajax_uploadFiles_totalbg" style="z-index:0; position:absolute;left:0px;top:4px;width:300px;height:12px;background-color:Gray"></div>
  35. </td>
  36. </tr>
  37. </table>
  38. <table style="color:White; width:100%">
  39. <tr>
  40. <td style="position:relative">
  41. <asp:Label runat="server" Font-Size="11pt" ID="ajax_uploadFiles_serverProcessTip"></asp:Label>
  42. </td>
  43. </tr>
  44. </table>

input file 控件的一些设置如下:

(1)onbeginupload="ajax_uploadFiles_beginUpload"   js方法,开始上传前事件,默认值

(2)onprogressupload="ajax_uploadFiles_progressUpload"   js方法,上传中事件,默认值

(3)onendupload="ajax_uploadFiles_endUpload"    js方法,选择完文件上传事件,默认值
(4)multiple="multiple"         控件属性,允许多文件选中上传

(5)allowtype="pptx|docx|mp3|txt|std"    自定义属性,允许上传的文件类型,以 | 分隔

(6)allowsize="500m|100m"    自定义属性,允许上传的文件最大尺寸,可以以 | 分隔,并一一对应,如果不对应,则根据 allowtype 的设置从左至右进行匹配

        如举例中的设置则表示为,pptx 允许最大 500M , docx 最大 100M,后面未设置则均为100M

(7) serverbuttonid="ajaxEndBtn"   自定义属性,执行的服务器按钮ID,默认值 

(8)serverfilelistid="ajaxReturnFileName"  自定义属性,服务器端返回的文件ID列表,默认值

(9)οnchange="ajax_uploadFiles(this);return false"  自定义属性,js方法,选择文件后自动执行上传功能,默认值

根据示例代码的设置,以上部分除了 allowtype和 allowsize 均可以不用改变设置。

上传中的效果如下图:

 

JavaScript包程序

本包程序实现了前面设置的界面元素方法、事件、属性的实现及对文件上传的客户端控制,示例代码如下:

  1.  //批量上传文件的内置默认辅助方法,表示每上传一个文件之前发生的事件,
  2.          //事件的fileObj参数代表 file对象(上传控件),由主方法自动传入,开发者可以重新指定自定义方法
  3.          function ajax_uploadFiles_beginUpload(fileObj) {
  4.             var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
  5.             if (fIndex == 0) {
  6.                 document.getElementById('ajax_uploadFiles_serverProcessTip').innerHTML = '';
  7.                 document.getElementById("ajax_uploadFiles_upprogress").innerHTML = "";
  8.                 document.getElementById("ajax_uploadFiles_cprogress").innerHTML = "";
  9.                 document.getElementById("ajax_uploadFiles_totalprogress").style.width = "0px";
  10.                 document.getElementById(fileObj.getAttribute("serverfilelistid")).value = "";
  11.             }
  12.             document.getElementById("ajax_uploadFiles_curfilename").innerHTML = fileObj.files[fIndex].name;
  13.         }
  14.         //批量上传文件的内置默认辅助方法,表示当前正在上传文件时发生的事件(主要用于显示上传进度),
  15.         //事件的fileObj参数代表 file对象(上传控件), loaded:已经上传的文件总字节, total:正在上传的文件总字数,
  16.         // percent:不超过100的整数,表示为百分比。这些参数由主方法自动传入,开发者可以重新指定自定义方法
  17.         function ajax_uploadFiles_progressUpload(fileObj, loaded, total, percent) {
  18.             document.getElementById("ajax_uploadFiles_upprogress").innerHTML = ("" + percent + "%");
  19.             var curb = parseInt(document.getElementById("ajax_uploadFiles_curbg").style.width, 10);
  20.             document.getElementById("ajax_uploadFiles_curprogress").style.width = Math.floor(curb * loaded / total) + "px";
  21.         }
  22.         //批量上传文件的内置默认辅助方法,表示当前文件上传完成时发生的事件(主要用于处理文件上传后的跟踪处理,并且返回服务器上保存的文件列到一个文本框中,以|分隔),
  23.         //事件的fileObj参数代表 file对象(上传控件), type:上传状态返回,包括success成功,error失败, 
  24.         //data:文件的数据,暂时未使用, desfile:要保存在服务器上的文件名
  25.         // 这些参数由主方法自动传入,开发者可以重新指定自定义方法
  26.         function ajax_uploadFiles_endUpload(fileObj, type, data, desfile) {
  27.             var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
  28.             var filecount = fileObj.files.length;
  29.             document.getElementById(fileObj.getAttribute("serverfilelistid")).value += desfile + "|";
  30.             var totalb = parseInt(document.getElementById("ajax_uploadFiles_totalbg").style.width, 10);
  31.             document.getElementById("ajax_uploadFiles_totalprogress").style.width = Math.floor(totalb * (fIndex + 1) / filecount) + "px";
  32.             document.getElementById("ajax_uploadFiles_cprogress").innerHTML = ("" + Math.floor(100 * (fIndex + 1) / filecount) + "%");
  33.             if (fIndex < filecount - 1) {
  34.                 fIndex++;
  35.                 fileObj.setAttribute("fileindex", fIndex);
  36.                 ajax_uploadFiles(fileObj);
  37.                 return;
  38.             }
  39.             fileObj.setAttribute("fileindex", 0);
  40.             if (type == "success") {
  41.                             document.getElementById('ajaxMfile').style.display='none';
  42.                 document.getElementById('ajax_uploadFiles_serverProcessTip').innerHTML = '上传完成!正在进行后台处理...';
  43.                 document.getElementById(fileObj.getAttribute("serverbuttonid")).click();
  44.             } else if (type == "error") {
  45.                 alert("error");
  46.             }
  47.         }
  48.         //生成一个guid
  49.         function newguid() {
  50.             function S4() {
  51.                 return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  52.             }
  53.             return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  54.         }
  55.         //批量上传文件的主方法,fileObj参数代表 file对象(上传控件)
  56.         function ajax_uploadFiles(fileObj) {
  57.             var formData = new FormData();
  58.             var fIndex = parseInt(fileObj.getAttribute("fileindex"), 10);
  59.             var filecount = fileObj.files.length;
  60.             if (filecount == 0) {
  61.                 alert('请先浏览选择文件...');
  62.                 return;
  63.             }
  64.             var uploadSessionId = newguid();
  65.             var upfile = fileObj.files[fIndex].name;
  66.             var dotpos = upfile.lastIndexOf('.');
  67.             var desfile = "";
  68.             var exname = "";
  69.             if (dotpos > 0) {
  70.                 exname = upfile.substring(dotpos + 1, upfile.length);
  71.                 desfile = uploadSessionId + upfile.substring(0, dotpos) + '.' + exname;
  72.             } else {
  73.                 desfile = uploadSessionId + upfile;
  74.             }
  75.             //        alert(Math.round(upsize / 1024));
  76.             if (fIndex == 0) {
  77.                 var allowtype = fileObj.getAttribute("allowtype");
  78.                 var allowsize = fileObj.getAttribute("allowsize");
  79.                 var at = allowtype.split('|');
  80.                 var as = allowsize.split('|');
  81.                 for (var j = 0; j < filecount; j++) {
  82.                     var validfile = fileObj.files[j].name;
  83.                     var upsize = fileObj.files[j].size;
  84.                     var validdotpos = validfile.lastIndexOf('.');
  85.                     var validexname = "";
  86.                     if (validdotpos > 0) {
  87.                         validexname = validfile.substring(validdotpos + 1, validfile.length);
  88.                     }
  89.                     var i = 0;
  90.                     if (allowtype != "") {
  91.                         var find = false;
  92.                         for (i = 0; i < at.length; i++) {
  93.                             if (at[i].toLowerCase() == validexname.toLowerCase()) {
  94.                                 find = true;
  95.                                 break;
  96.                             }
  97.                         }
  98.                         if (find == false) {
  99.                             alert("文件" + validfile + "上传的类型不符合要求!仅允许上传扩展名为:" + allowtype.split("|").join("、") + "的文件。");
  100.                             fileObj.style.display = '';
  101.                             document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
  102.                             var t = fileObj;
  103.                             t.outerHTML = t.outerHTML;
  104.                             return;
  105.                         }
  106.                     }
  107.                     if (allowsize != "") {
  108.                         if (at.length <= as.length) {
  109.                         } else {
  110.                             i = 0;
  111.                         }
  112.                         as[i] = as[i].toLowerCase();
  113.                         var csize = parseInt(as[i]);
  114.                         var tsize = upsize;
  115.                         if (as[i].lastIndexOf('k') != -1) {
  116.                             csize = csize * 1024;
  117.                             tsize = Math.round(upsize / 1024) + "KB";
  118.                         } else if (as[i].lastIndexOf('m') != -1) {
  119.                             csize = csize * 1024 * 1024;
  120.                             tsize = Math.round(upsize / 1024 / 1024) + "MB";
  121.                         } else if (as[i].lastIndexOf('g') != -1) {
  122.                             csize = csize * 1024 * 1024 * 1024;
  123.                             tsize = Math.round(upsize / 1024 / 1024 / 1024) + "GB";
  124.                         } else if (as[i].lastIndexOf('t') != -1) {
  125.                             csize = csize * 1024 * 1024 * 1024 * 1024;
  126.                             tsize = Math.round(upsize / 1024 / 1024 / 1024 / 1024) + "TB";
  127.                         }
  128.                         if (upsize > csize) {
  129.                             alert("上传文件" + validfile + "的大小近" + tsize + ",系统规定大小不能超过" + as[i].toUpperCase() + ",请重新选择。");
  130.                             fileObj.style.display = '';
  131.                             document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
  132.                             var t = fileObj;
  133.                             t.outerHTML = t.outerHTML;
  134.                             return;
  135.                         }
  136.                     }
  137.                 } //j
  138.             } // findex
  139.             //        document.getElementById(callObjId).disabled = 'disabled';
  140.             //        if (beginFuncName != null) {
  141.             //            beginFuncName(fIndex, filecount,upfile);
  142.             //        }
  143.             fileObj.style.display = 'none';
  144.             document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = '';
  145.             var findfunc = fileObj.getAttribute("onbeginupload");
  146.             if (eval(findfunc)) {
  147.                 var execfunc = eval(findfunc);
  148.                 //            alert(findfunc);
  149.                 execfunc(fileObj);
  150.             }
  151.             formData.append("file", fileObj.files[fIndex]); //append()里面的第一个参数file对应permission/upload里面的参数file
  152.             var processUploadUrl = window.location.protocol + "//" + window.location.host + "//common//uploadfile.ashx?guid=" + uploadSessionId;
  153.             $.ajax({
  154.                 type: "post",
  155.                 async: true,  //这里要设置异步上传,才能成功调用myXhr.upload.addEventListener('progress',function(e){}),progress的回掉函数
  156.                 Accept: 'text/html;charset=UTF-8',
  157.                 data: formData,
  158.                 contentType: "multipart/form-data",
  159.                 url: processUploadUrl,
  160.                 processData: false, // 告诉jQuery不要去处理发送的数据
  161.                 contentType: false, // 告诉jQuery不要去设置Content-Type请求头
  162.                 xhr: function () {
  163.                     myXhr = $.ajaxSettings.xhr();
  164.                     if (myXhr.upload) { // check if upload property exists
  165.                         myXhr.upload.addEventListener('progress', function (e) {
  166.                             var loaded = e.loaded;                  //已经上传大小情况 
  167.                             var total = e.total;                      //附件总大小 
  168.                             var percent = Math.floor(100 * loaded / total);     //已经上传的百分比  
  169.                             //                        if (progressFuncName != null) {
  170.                             //                            progressFuncName(loaded, total, percent);
  171.                             //                        }
  172.                             var findfunc = fileObj.getAttribute("onprogressupload");
  173.                             if (eval(findfunc)) {
  174.                                 var execfunc = eval(findfunc);
  175.                                 //            alert(findfunc);
  176.                                 execfunc(fileObj, loaded, total, percent);
  177.                             }
  178.                             //                            $("#processBar").css("width", percent);
  179.                         }, false); // for handling the progress of the upload
  180.                     }
  181.                     return myXhr;
  182.                 },
  183.                 success: function (data) {
  184.                     if (fIndex == fileObj.files.length - 1) {
  185.                         fileObj.style.display = '';
  186.                         document.getElementById(fileObj.getAttribute("progresspanelid")).style.display = 'none';
  187.                         var t = fileObj;
  188.                         t.outerHTML = t.outerHTML;
  189.                     }
  190.                     //                if (endFuncName != null) {
  191.                     //                    endFuncName("success", data, desfile, fIndex,filecount);
  192.                     //                }
  193.                     var findfunc = fileObj.getAttribute("onendupload");
  194.                     if (eval(findfunc)) {
  195.                         var execfunc = eval(findfunc);
  196.                         //            alert(findfunc);
  197.                         execfunc(fileObj, "success", data, desfile);
  198.                     }
  199.                 },
  200.                 error: function (XMLHttpRequest, textStatus, errorThrown) {
  201.                     alert(errorThrown);
  202.                     if (endFuncName != null) {
  203.                         endFuncName(fileObj, "error", null, '');
  204.                     }
  205.                 }
  206.             });
  207.         } 

服务端 ashx 程序

ashx,一般处理程序(HttpHandler)是·NET众多web组件的一种。一个 httpHandler 接受并处理一个http请求,类似 Java 中的 servlet 。

本程序实现服务器端上传文件的接收和另存操作,在这里我们存为uploadfile.ashx,代码如下:

  1. <%@ WebHandler Language="C#" Class="Handler" %>
  2. using System;
  3. using System.Web;
  4. using System.IO;
  5. public class Handler : IHttpHandler {
  6.     
  7.     public void ProcessRequest (HttpContext context) {
  8.         if (context.Request.Files.Count > 0)
  9.         {
  10.             //HttpContext.Current.Request.FilePath;
  11.             string strPath = System.Web.HttpContext.Current.Server.MapPath("~/app_data/ajaxUploadFiles/");
  12.             string strName = context.Request.Files[0].FileName;
  13.             string ext=Path.GetExtension(strName);
  14.             string filename =HttpContext.Current.Request.QueryString["guid"].ToString()+Path.GetFileNameWithoutExtension(strName);
  15.             if(ext!=""){
  16.                 filename = filename  + ext;
  17.             }
  18.             context.Request.Files[0].SaveAs(System.IO.Path.Combine(strPath, filename));
  19.         }
  20.     }
  21.  
  22.     public bool IsReusable {
  23.         get {
  24.             return false;
  25.         }
  26.     }
  27. }

服务端上传后处理程序

在多个文件上传到服务器后,我们需要对文件进行后期处理,在前端我们设置了ID为 “ajaxEndBtn”的服务器按钮,进行模拟调用其 click 事件。

服务器端按钮处理事件示例代码如下:

  1. void ajaxEndBtn_Click(object sender, EventArgs e)
  2. {
  3. //得到保存后的文件名列表
  4. string[] upfiles = ajaxReturnFileName.Text.Split('|');
  5. //给予用户基本的提示
  6. ajax_uploadFiles_serverProcessTip.Text = "本次上传分析:共计上传" + (upfiles.Length - 1).ToString() + "个文件。";
  7. //遍历上传文件列表,进行后期处理
  8. foreach (string filename in upfiles)
  9. {
  10. if (filename.Trim() == "") continue;
  11. string upfilename = Request.PhysicalApplicationPath + "app_data\\ajaxUploadFiles\\" + filename;
  12. string exname = System.IO.Path.GetExtension(upfilename);
  13. //执行业务处理程序
  14. }

 

小结

以上提供的代码仅供参考,默认的设置仅可能提供最基础的实现,比如 ashx 程序还需要进行安全控制;进度图片和UI可以重新设计;实际的业务可以根据需求对控件的属性、事件进行重写。

以上就是自己的一些分享,时间仓促,不妥之处还请大家批评指正!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/39223
推荐阅读
相关标签
  

闽ICP备14008679号