Tag: Multiple upload file

  • ทำอย่างไรให้เว็บไซต์ที่เราพัฒนาสามารถอัพโหลดไฟล์แบบคราวละหลายไฟล์ได้โดยไม่จำกัดจำนวน ด้วย ASP.NET(C#)

              ในการพัฒนาเว็บไซต์ บางครั้งอาจมีความจำเป็น หรือความต้องการจากผู้ใช้ที่ต้องการให้เว็บไซต์ดังกล่าวมีฟังก์ชั่นการทำงานในส่วนของการอัพโหลดไฟล์เพื่อแนบไฟล์เข้าไปในระบบและบันทึกลงฐานข้อมูล เพื่อให้สามารถเรียกดูข้อมูลการแนบไฟล์ดังกล่าวได้ในภายหลัง การอัพโหลดไฟล์จึงถือเป็นอีกหนึ่งฟังก์ชั่นการทำงานที่นักพัฒนาเว็บไซต์ควรทราบไว้ ซึ่งลักษณะการทำงานโดยทั่วไปส่วนใหญ่เราจะใช้ Control ที่มีเรียกว่า “FileUpload” แบบอัพโหลดครั้งละ 1 ไฟล์ และหากมีมากกว่านั้นก็จะมีการสร้างตัว FileUpload มาวางไว้ในหน้าจอเพิ่มตามจำนวนที่ต้องการแบบตายตัว เช่น หากในหน้าจอดังกล่าวต้องการสามารถให้ทำการอัพโหลดไฟล์ได้ไม่เกิน 5 ไฟล์ต่อการอัพโหลดแต่ละครั้งก็จะมีการลากคอนโทรล FileUpload มาวางไว้ในหน้าจอจำนวน 5 ตัว เพื่อให้สามารถรองรับความต้องการในการอัพโหลดไฟล์ของผู้ใช้ได้ แต่ผู้เขียนพบว่าการทำงานดังกล่าวอาจไม่รองรับความต้องการในการทำงานของผู้ใช้ที่จะเพิ่มไฟล์ได้ครั้งละหลายๆไฟล์โดยไม่จำกัดและผู้พัฒนาไม่จำเป็นต้องระบุหรือสร้างคอนโทรล FileUpload มาวางในหน้าจอในจำนวนที่ตายตัวโดยไม่จำเป็น โดยผู้ใช้สามารถคลิกปุ่มเพื่อเพิ่มจำนวนในการอัพโหลดไฟล์แต่ละครั้งได้เองเพื่อความยืดหยุ่นในการใช้งาน ในบทความนี้ ผู้เขียนจึงขอเสนอแนวทางในการพัฒนาเว็บไซต์โดยใช้ ASP.NET(C#) ในแบบที่มีการอัพโหลดไฟล์ได้คราวละหลายๆไฟล์ในแบบไม่ต้องจำกัดจำนวนคอนโทรล FileUpload ในหน้าจอโดยมีการระบุจำนวนไฟล์ที่สามารถอัพโหลดได้ในแต่ละครั้งโดยผู้พัฒนาแบบตายตัวอย่างเช่นที่กล่าวไว้ข้างต้น

              หลังจากที่ได้มีการศึกษาเพิ่มเติม ผู้เขียนพบว่าใน .NET Framework เวอร์ชั่น 4.5 นั้นจะมีการเพิ่ม Feature การทำงานในส่วนนี้ให้กับคอนโทรล FileUpload ไว้แล้วผ่าน Properties ที่เรียกว่า AllowMultiple ซึ่งจะทำให้สะดวกต่อการพัฒนาและสามารถลดปัญหาดังกล่าวข้างต้นได้ แต่สำหรับเวอร์ชั่นที่ต่ำกว่ายังคงต้องมีการปรับปรุงพัฒนาเพิ่มเติมเอง ในบทความนี้จึงขอยกตัวอย่างการพัฒนาทั้ง 2 แบบในเบื้องต้นโดยจะเน้นไปในแบบเวอร์ชั่นที่ต่ำกว่า 4.5 เพื่อให้ผู้อ่านได้นำไปเป็นแนวทางในการพัฒนาต่อไป ดังนี้
    1. การอัพโหลดไฟล์คราวละหลายๆไฟล์โดยใช้ .Net Framework เวอร์ชั่นที่ต่ำกว่า 4.5

              ในบทความนี้ ผู้เขียนขอเสนอแนวทางแบบที่เป็นการพัฒนาโดยใช้จาวาสคริปต์เข้ามาเป็นตัวช่วยให้สามารถอัพโหลดไฟล์ได้ครั้งละหลายไฟล์ต่อการอัพโหลดแต่ละครั้ง เพื่อลดจำนวนการโหลดของหน้าจอและทำให้ผู้ใช้รู้สึกว่าการทำงานดังกล่าวเป็นไปด้วยความรวดเร็วไม่ต้องใช้เวลานาน โดยจะอธิบายทีละขั้นตอน ดังนี้

    1) ออกแบบหน้าจอการทำงานในฝั่ง Client  ทำการออกแบบหน้าจอการทำงานไว้ในเบื้องต้น โดยมีการสร้างคอนโทรล FileUpload มาตั้งต้นไว้ 1 ตัว และมีปุ่มเพื่อให้ทำการเพิ่มคอนโทรล FileUpload ได้เองอัตโนมัติโดยตัวผู้ใช้เอง และปุ่มที่ใช้ในการอัพโหลดไฟล์จากคอนโทรล FileUpload ทั้งหมด ดังนี้

    <body>
    <form id="form1" runat="server">
    <div>
     <div id="fileUploadarea" class="Divborder">
      <div id='divfirstUpload'><br /><asp:FileUpload ID="fuMultiple" runat="server" CssClass="fileUpload" onchange="javascipt:FileValidate(this,5);" />&nbsp;  <input style="display:inline;" id="BtnRemove" type="button" value="Remove" onclick="DelFileUpload('divfirstUpload');" /> 
    </div> 
    </div>
    <br /> 
    <div>&nbsp; 
    <input style="display:inline; background-color: #A4EDFF; color: #333333; width: 150px; font-weight: bold;" id="btnAddMoreFiles" type="button" value="Add more files" onclick="AddMoreFilesWithMax(6);" />
    &nbsp; <asp:Button ID="BtnUpload" runat="server" onclick="BtnUpload_Click" Text="Upload" OnClientClick="return ValidateFileUpload();" BackColor="#3399FF" Font-Bold="True" ForeColor="White" Width="150px" /> 
    <br> 
    <asp:GridView ID="gvResult" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" Width="410px">
    <RowStyle BackColor="#EFF3FB" /> 
    <Columns> 
    <asp:BoundField DataField="Name" HeaderText="ชื่อไฟล์"> 
    <ItemStyle Width="200px" /> </asp:BoundField> 
    <asp:BoundField DataField="FileSize" HeaderText="ขนาดไฟล์(KB)"> 
    <ItemStyle HorizontalAlign="Right" Width="120px" /> 
    </asp:BoundField> 
    </Columns> 
    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> 
    <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> 
    <EditRowStyle BackColor="#2461BF" /> <AlternatingRowStyle BackColor="White" /> 
    </asp:GridView> 
    </div> 
    </div> 
    </form> 
    </body>

    2) ในส่วนของจาวาสคริปต์ที่ใช้เป็นตัวช่วยในการตรวจสอบ โดยจะแยกเป็นแต่ละ function ดังนี้

    2.1) ฟังก์ชั่นที่ใช้ในการเพิ่มไฟล์ได้ไม่จำกัด โดยใช้ชื่อว่า AddMoreFiles()

    <script language="javascript" type="text/javascript">
    
    function AddMoreFiles() {
    
      if (!document.getElementById && !document.createElement)
        return false;
    ////อ้างอิงถึง div ที่มีชื่อว่าfileUploadarea
      var fileUploadarea = document.getElementById("fileUploadarea"); 
      if (!fileUploadarea) return false; 
       var newLine = document.createElement("br"); fileUploadarea.appendChild(newLine); 
       var newFile = document.createElement("input"); 
       newFile.type = "file"; newFile.setAttribute("class", "fileUpload");
    
    /////กำหนดค่าเริ่มต้นให้กับตัวแปร AddMoreFiles.lastAssignedId 
    เพื่อใช้ในการกำหนด ID ให้กับคอนโทรลที่สร้างขึ้น และเป็นตัวนับ
      if (!AddMoreFiles.lastAssignedId) 
        AddMoreFiles.lastAssignedId = 1;
    
     //////กำหนดค่าแอททริบิวต์ต่างๆให้กับ FileUpload ที่ทำการสร้างใหม่ ในทีนี้คือ id และ name
        newFile.setAttribute("id", "FileUpload" + AddMoreFiles.lastAssignedId);  
        newFile.setAttribute("name", "FileUpload" + AddMoreFiles.lastAssignedId); 
    
     //////สร้าง div ขึ้นมาใหม่ และกำหนดค่าแอททริบิวต์ต่างๆให้กับ div ที่ทำการสร้างใหม่ 
    ในทีนี้คือ id และ เพิ่มคอนโทรลที่สร้าง tag ไว้ด้านบนเข้ามาไว้ใน div 
        var div = document.createElement("div"); 
        div.appendChild(newFile); 
        div.setAttribute("id", "div" + AddMoreFiles.lastAssignedId); 
    
    //////เพิ่ม div ที่สร้างใหม่ไปยัง div ที่มีชื่อว่า fileUploadarea และเพิ่มค่าของตัวแปร AddMoreFiles.lastAssignedId   
        fileUploadarea.appendChild(div); 
        AddMoreFiles.lastAssignedId++; 
    }

    2.2) ฟังก์ชั่นที่ใช้ในการเพิ่มไฟล์ได้โดยมีการระบุจำนวนสูงสุดที่ยอมให้อัพโหลดแต่ละครั้ง ในกรณีที่ต้องการระบุค่าจำนวนไฟล์ที่ต้องการให้ผู้ใช้สามารถอัพโหลดได้สูงสุดในแต่ละครั้ง สามารถปรับแก้เพิ่มเติมจากฟังก์ชั่นก่อนหน้านี้ โดยการส่งพารามิเตอร์จำนวนมากสุดที่ยอมให้สร้างตัวอัพโหลดไฟล์ได้ โดยใช้ชื่อฟังก์ชั่นว่า AddMoreFilesWithMax(x) ดังนี้

    function AddMoreFilesWithMax(x) 
    { //////กำหนดค่าให้กับ AddMoreFiles.lastAssignedId 
    เพื่อเป็นค่าตั้งต้นในการไปเซทค่า id และ name ของคอนโทรลที่สร้างใหม่ 
    โดยในที่นี้เริ่มต้นที่ 2 เนื่องจากเดิมมีคอนโทรลอัพโหลดไฟล์อยู่เดิมแล้ว 1 ตัว
      if (!AddMoreFiles.lastAssignedId)
          AddMoreFiles.lastAssignedId = 2;
    
       if (!document.getElementById && !document.createElement)
          return false; 
      var fileUploadarea = document.getElementById("fileUploadarea");
        if (!fileUploadarea) return false;
    
    /////เป็นการตรวจสอบเงื่อนไขว่ายังไม่เกินจำนวนมากสุดที่ระบุไว้ผ่านพารามิเตอร์ x
          if (AddMoreFiles.lastAssignedId <= x) 
          { 
          var newLine = document.createElement("br"); 
    
          //สร้างปุ่ม Remove เพื่อใช้ลบคอนโทรล FileUpload ที่สร้างขึ้นออกโดยผู้ใช้ 
          var newbtnDel = document.createElement("input"); 
          newbtnDel.setAttribute("id", "btnDelUpload" + AddMoreFiles.lastAssignedId);
          newbtnDel.setAttribute("name", "btnDelUpload" + AddMoreFiles.lastAssignedId); 
          newbtnDel.setAttribute("value", "Remove");   
          newbtnDel.type = "button"; 
    
         //////สร้างคอนโทรล FileUpload ขึ้นใหม่และกำหนดแอททริบิวต์ต่างๆให้
          var newFile = document.createElement("input"); 
          newFile.type = "file"; 
          newFile.setAttribute("class", "fileUpload");
          newFile.setAttribute("id", "FileUpload" + AddMoreFiles.lastAssignedId); 
          newFile.setAttribute("name", "FileUpload" + AddMoreFiles.lastAssignedId);
    
    //////เป็นส่วนของการเรียกฟังก์ชั่นในการตรวจสอบไฟล์ที่ทำการอัพโหลดว่าถูกต้องตรงตามเงื่อนไขหรือไม่
         เมื่อมีการเลือกไฟล์ใดๆจากผู้ใช้ ซึ่งจะพูดถึงในส่วนถัดไปในการสร้างฟังก์ชั่น FileValidate(ctrl,maxVal) 
          newFile.setAttribute('onchange', 'javascipt:FileValidate(this,5);');
    
    //////สร้าง div ขึ้นมาใหม่ และกำหนดค่าแอททริบิวต์ต่างๆให้กับ div ที่ทำการสร้างใหม่ 
    ในทีนี้คือ id และ เพิ่มคอนโทรลที่สร้าง tag ไว้ด้านบนเข้ามาไว้ใน div 
          var div = document.createElement("div");
          div.appendChild(newLine);
          div.appendChild(newFile);
    //////เพิ่มช่องว่างระหว่างคอนโทรลอัพโหลดไฟล์และปุ่ม Remove เพื่อความสวยงาม
          div.appendChild(document.createTextNode('\u00A0'));
          div.appendChild( newbtnDel);
          div.setAttribute("id", "div" + AddMoreFiles.lastAssignedId);
    
    //////เพิ่ม event การคลิกปุ่ม Remove เพื่อให้ไปเรียกใช้ฟังก์ชั่น DelFileUpload
    โดยส่งค่า id ของ div ที่ต้องการให้ลบออกซึ่งจะกล่าวถึงในส่วนถัดไปของการสร้างฟังก์ชั่น DelFileUpload(divid);
          newbtnDel.setAttribute('onclick', 'javascipt:DelFileUpload(\'' + "div" + AddMoreFiles.lastAssignedId + '\');');
    
          fileUploadarea.appendChild(div);
          AddMoreFiles.lastAssignedId++; } 
    
    ///////กรณีที่มีจำนวนตัวอัพโฟลดไฟล์ที่ถูกสร้างขึ้นเองเกินกว่าที่กำหนด(ค่าพารามิเตอร์ x) 
    จะแสดงข้อความให้ทราบ
     else { 
           alert("ขออภัย ท่านสามารถอัพโหลดไฟล์ได้สูงสุดครั้งละไม่เกิน " + x + " ไฟล์ต่อการอัพโหลดแต่ละครั้ง กรุณาลองใหม่อีกครั้ง"); 
          return false;
           } 
          }

    2.3) ฟังก์ชั่นที่ใช้ในการตรวจสอบขนาดของไฟล์ โดยมีการระบุขนาดสูงสุดที่ยอมให้อัพโหลดแต่ละครั้ง โดยใช้ชื่อฟังก์ชั่นว่า FileValidate(ctrlFile,MaxSize)

    ////เป็นการประกาศตัวแปรที่ใช้ในการตรวจสอบชนิดของไฟล์ที่ยอมให้อัพโหลดได้
    var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png", ".pdf"];
    function FileValidate(ctrlFile,MaxSize) 
    {//////พารามิเตอร์ที่รับเข้ามาคือตัวคอนโทรลของการอัพโหลดไฟล์ที่ต้องการตรวจสอบ(ctrlFile) 
    และขนาดสูงสุดของไฟล์ที่ยอมให้อัพโหลดในแต่ละคอนโทรล(MaxSize)
    
    ////ดึงค่าชื่อของไฟล์ที่อัพโหลดที่ต้องการตรวจสอบ
      var sFileName = ctrlFile.value;
    
    /////ตรวจสอบเมื่อพบชื่อไฟล์ที่ดึง
       if (sFileName.length > 0) 
       { 
         var blnValid = false; 
    //////////ตรวจสอบนามสกุลของไฟล์ที่ดึงมาจากชื่อไฟล์กับค่าของนามสกุลไฟล์ที่ยอมให้อัพโหลด
    จากตัวแปร _validFileExtensions
         for (var j = 0; j < _validFileExtensions.length; j++) 
          { var sCurExtension = _validFileExtensions[j]; 
           if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) 
           { 
             blnValid = true; 
             break; 
            } 
          }   
    //////กรณีไฟล์ดังกล่าวมีนามสกุลที่แตกต่างจากที่กำหนดจะแสดงข้อความแจ้งเตือน 
    และล้างค่าของชื่อไฟล์ในคอนโทรลอัพโหลดไฟล์ตัวดังกล่าว
         if (!blnValid) 
         { alert("ไม่สามารถอัพโหลดไฟล์ดังกล่าวได้ เนื่องจากรองรับเฉพาะไฟล์ที่มีนามสกุลดังนี้เท่านั้น: " + _validFileExtensions.join(", ")); 
          ctrlFile.value = ""; 
          return false; 
         } 
         else 
         {
    /////หากไฟล์ที่อัพโหลดมีนามสกุลไฟล์ตามที่ระบุ จะทำการตรวจสอบขนาดของไฟล์ว่าไม่เกินจากขนาดสูงสุด
    ที่กำหนดหรือไม่ โดยมีการคำนวณหน่วยเป็น MB
           var fileSize = parseFloat(ctrlFile.files[0].size / 1048576).toFixed(2);
    
    /////หากขนาดของไฟล์เกินกว่าที่กำหนดจะแสดงข้อความแจ้งเตือน และล้างค่าไฟล์ที่ต้องการอัพโหลด
    ในคอนโทรลอัพโหลดไฟล์ดังกล่าว
           if (fileSize > MaxSize) 
            { alert(" ขออภัย ขนาดของไฟล์ที่ต้องการอัพโหลดมีขนาดใหญ่เกินกว่าทีกำหนด(" + MaxSize + " MB)"); 
              ctrlFile.value = ""; 
              return false;   
           } 
         }   
        }   
      return true; 
      }

    2.4) ฟังก์ชั่นที่ใช้ในการตรวจสอบว่ามีการเลือกไฟล์ที่ต้องการอัพโหลดแล้วหรือไม่ เมื่อมีการกดปุ่ม “Upload” โดยใช้ชื่อฟังก์ชั่นว่า ValidateFileUpload() 

    function ValidateFileUpload() { 
    //////เป็นการค้นหาคอนโทรลไฟล์อัพโหลดที่มีในหน้าจอโดยใช้ tag input 
    และตรวจสอบที่มี type เป็น "file" ใส่ไว้ในตัวแปร arrInputs
        var arrInputs = document.getElementsByTagName("input");
        var blnValid; 
        var oInput;
        for (var i = 0; i < arrInputs.length; i++)
         { oInput = arrInputs[i]; 
          if (oInput.type == "file") 
          { 
           var sFileName = oInput.value; 
    
     ///////หากพบตัวอัพโหลดไฟล์ตัวใดที่ยังไม่ได้ทำการเลือกไฟล์ไว้ จะทำการแสดงข้อความแจ้งเตือนให้ทราบ
           if (sFileName.length == 0) 
             { blnValid = false; 
              alert("ขออภัย ไม่สามารถอัพโหลดไฟล์ได้ เนื่องจากพบว่ามีบางไฟล์ไม่ได้ถูกเลือก กรุณาลองใหม่อีกครั้ง"); 
              return false;   
             } 
          }   
         }   
    return true; 
    }

    2.5) ฟังก์ชั่นที่ใช้ในการลบคอนโทรลที่ใช้ในการอัพโหลดไฟล์ โดยใช้ชื่อฟังก์ชั่นว่า DelFileUpload(dv) ซึ่งจะส่งพารามิเตอร์เป็น id ของ div ตัวที่ต้องการให้ลบ และถูกเรียกใช้เมื่อมีการกดปุ่ม “Remove”

    function DelFileUpload(dv) 
    { ////ค้นหา div ตาม id ที่ส่งเข้ามา
       var elem = document.getElementById(dv); 
      ///ทำการลบ div นั้นออกจากหน้าจอและลดค่าของ AddMoreFiles.lastAssignedId ลง 1
    เพื่อใช้ในการคำนวณค่าสูงสุดและกำหนด tag ของ id และ name ของคอนโทรลที่สร้างใหม่ต่อไป
       elem.parentNode.removeChild(elem); 
       AddMoreFiles.lastAssignedId = AddMoreFiles.lastAssignedId - 1; 
    }

    3) ในฝั่งเซฺิร์ฟเวอร์ (C#)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    /////เป็น namespace ที่ต้องอ้างอิงเพิ่มเพื่อใช้ในการจัดการข้อมูลกับ datatable
    using System.Data;
    /////เป็น namespace ที่ต้องอ้างอิงเพิ่มเพื่อใช้ในการจัดการเกี่ยวกับการอัพโหลดไฟล์
    using System.IO;
    public partial class MultipleUpload : System.Web.UI.Page
    {
    protected void BtnUpload_Click(object sender, EventArgs e)
    {
      try
      {
    
     //////สมมุติเพื่อนำไปประยุกต์ใช้กับการบันทึกลงฐานข้อมูลต่อไป 
    โดยสร้างโครงสร้าง datatable ที่ชื่อว่า dtFiles 
         DataTable dtFiles = new DataTable();
         dtFiles.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
         new DataColumn("Name", typeof(string)),
         new DataColumn("FileSize",typeof(string)) });
    
    ////เป็นการดึงคอนโทรลในการอัพโหลดไฟล์ที่ถูกสร้างขึ้นและวนรอบในการบันทึกไฟล์ดังกล่าว
     HttpFileCollection hfc = Request.Files;
     for (int i = 0; i < hfc.Count; i++)
     {
        HttpPostedFile hpf = hfc[i];
       if (hpf.ContentLength > 0)
        {
    //////บันทึกไฟล์ตามที่ระบุไว้
        hpf.SaveAs(Server.MapPath("~/uploads/") + System.IO.Path.GetFileName(hpf.FileName));
    
    ////เพิ่มข้อมูลลงไปใน datatable ที่สร้างไว้ สำหรับการใช้งานจริงอาจเป็นการติดต่อเพื่อบันทึกลงฐานข้อมูล 
        dtFiles.Rows.Add(i,hpf.FileName, hpf.ContentLength / 1024);
         }
       }
     if (dtFiles.Rows.Count > 0) 
     {
    //////ดึงข้อมูลจาก datatable มาแสดงในกริดวิว
        gvResult.DataSource = dtFiles;
        gvResult.DataBind();
     
     }
       }
      }
      catch (Exception)
      {
       throw;
       }
      }
    }
    

    เพิ่มเติม :
    หากต้องการตกแต่งเพื่อความสวยงามสามารถใส่ StyleSheet เพิ่มเติมได้ ดังตัวอย่างต่อไปนี้

    <style type="text/css">
      .fileUpload
      {
       width:255px;
       font-size:11px;
       color:#000000;
       border:solid;
       border-width:1px;
       border-color:#7f9db9;
       height:17px;
      }
     .Divborder
      {
       border: 2px solid;
       border-radius: 5px;
       padding:10px;
       width:390px;
      }
    </style>
    

    ตัวอย่างผลลัพธ์ที่ได้

    1) แสดงหน้าจอ โดยแรกเริ่มมีอัพโหลดไฟล์ตั้งต้น 1 ตัว

    uploadsingle

    2) แสดงหน้าจอเมื่อมีการกดปุ่ม “Add more files” uploadmulti2

    3) แสดงผลลัพธ์หลังจากบันทึกข้อมูลเรียบร้อยแล้วmultipleResult2

    2. การอัพโหลดไฟล์คราวละหลายๆไฟล์โดยใช้ .Net Framework เวอร์ชั่น 4.5  ซึ่งในบทความนี้จะไม่ลงรายละเอียดมากนัก ผู้อ่านสามารถนำไปประยุกต์เพิ่มเติมได้ โดยจะอธิบายทีละขั้นตอนคร่าวๆ ดังนี้

    1) การออกแบบในหน้าจอฝั่ง Client

    <body>
    <form id="form1" runat="server">
    <div>
    <asp:FileUpload ID="file_upload" runat="server" AllowMultiple="true" />
    <asp:Button ID="btnFileUpload" runat="server" Text="Upload" OnClick="btnFileUpload_Click" />
    <asp:Label ID="lblUploadStatus" runat="server"></asp:Label><br />
     <asp:GridView ID="gvResult" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" Width="410px">
     <AlternatingRowStyle BackColor="White" />
     <Columns>
     <asp:BoundField DataField="Name" HeaderText="ชื่อไฟล์">
     <ItemStyle Width="300px" />
     </asp:BoundField>
     <asp:BoundField DataField="filesize" HeaderText="ขนาดไฟล์(KB)">
     <ItemStyle HorizontalAlign="Right" Width="110px" />
     </asp:BoundField>
     </Columns>
     <EditRowStyle BackColor="#2461BF" />
     <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
     <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
     <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
     <RowStyle BackColor="#EFF3FB" />
     <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
     <SortedAscendingCellStyle BackColor="#F5F7FB" />
     <SortedAscendingHeaderStyle BackColor="#6D95E1" />
     <SortedDescendingCellStyle BackColor="#E9EBEF" />
     <SortedDescendingHeaderStyle BackColor="#4870BE" />
     </asp:GridView>
    </div>
    </form>
    </body>

    2) การพัฒนาในฝั่งเซิร์ฟเวอร์(C#)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.IO;
    using System.Data;
    namespace WebAppTest
    {
     public partial class MultipleUpload : System.Web.UI.Page
     {
     protected void btnFileUpload_Click(object sender, EventArgs e)
     {
     try
     {
    ///////การตรวจสอบขนาดไฟล์และไฟล์ต้องเป็นชนิด image/jpeg เท่านั้น
     if (file_upload.HasFile && file_upload.PostedFiles.All(x => x.ContentType == "image/jpeg" && x.ContentLength < 102400))
     {
    ///////ประกาศตัวแปร และกำหนดโครงสร้างของ datatable
     int i = 1;
     DataTable dtFiles = new DataTable();
     dtFiles.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
     new DataColumn("Name", typeof(string)),
     new DataColumn("FileSize",typeof(string)) });
     foreach (var file in file_upload.PostedFiles)
     {
    //////บันทึกไฟล์ที่เลือก
       file_upload.SaveAs(Server.MapPath("~/Fileupload/") + Path.GetFileName(file.FileName));
    ////วนบันทึกข้อมูลไฟล์ที่อัพโหลดลงใน datatable  
        dtFiles.Rows.Add(i, file.FileName, file.ContentLength / 1024);
     }
    
    ////แสดงข้อความเมื่อการอัพโหลดเสร็จสมบูรณ์
       lblUploadStatus.Text = "บันทึกสำเร็จ";
    
    ////แสดงค่าที่ได้ลงในกริดวิว
     if (dtFiles.Rows.Count > 0)
     {
     gvResult.DataSource = dtFiles;
     gvResult.DataBind();
    
     }
     }
     else
     {
    ////แสดงข้อความแจ้งเตือนกรณีเกิดปัญหาไฟล์มีขนาดใหญ๋เกินกว่าที่กำหนดและไม่ใช่ชนิด image/jpeg
       lblUploadStatus.Text = "กรุณาเลือกไฟล์ที่ต้องการอัพโหลดให้เหมาะสม";
     }
     }
     catch (Exception ex)
     {
    ////แสดงข้อความแจ้งเตือนกรณีเกิดปัญหาในการอัพโหลดไฟล์
       lblUploadStatus.Text = "เกิดข้อผิดพลาดในการอัพโหลดไฟล์ :" + ex.Message;
     }
     }
     }
    }

    ตัวอย่างผลลัพธ์ที่ได้

    1) ก่อนทำการอัพโหลดไฟล์

    multiple4_5_0

    2) หลังอัพโหลดไฟล์ทั้งหมดเรียบร้อยแล้ว

    multiple4_5

    หมายเหตุ : หากกำหนดค่าให้กับ Properties ที่ชื่อว่า AllowMultiple=”false ตอนเลือกไฟล์ที่จะอัพโหลดจะสามารถเลือกได้เพียงไฟล์เดียวเท่านั้น

              จากบทความและตัวอย่างข้างต้น จะเห็นว่า ลักษณะผลลัพธ์ที่ได้จะคล้ายคลึงกัน แต่จะแตกต่างกันในส่วนของความซับซ้อนในการตรวจสอบความถูกต้องของข้อมูลไฟล์แนบที่รับเข้ามา ซึ่งผู้พัฒนาเองสามารถเลือกใช้วิธีที่ตนถนัดและขึ้นกับเวอร์ชั่นของ .NET Framework ที่กำลังพัฒนา รวมถึงเงื่อนไขของการตรวจสอบให้ตรงตามความต้องการของผู้ใช้มากที่สุด โดยเนื้อหาในบทความนี้เป็นเพียงแนวทางหนึ่งให้กับท่านในเบื้องต้นเท่านั้น ท่านสามารถนำไปประยุกต์ต่อยอดเพิ่มเติมได้ และผู้เขียนหวังเป็นอย่างยิ่งว่าบทความนี้จะเป็นประโยชน์กับผู้พัฒนาที่กำลังค้นหาวิธีการอัพโหลดไฟล์คราวละหลายไฟล์นี้อยู่เช่นกัน หากมีเนื้อหาส่วนใดผิดพลาด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วย ขอบคุณค่ะ ^^
    แหล่งข้อมูลอ้างอิง :
    http://www.aspsnippets.com/Articles/Uploading-Multiple-Files-using-JavaScript-Dynamic-FileUpload-Controls-in-ASP.Net.aspx
    http://www.codeproject.com/Articles/667604/Upload-multiple-files-in-asp-net
    http://www.c-sharpcorner.com/UploadFile/99bb20/upload-multiple-files-using-fileupload-control-in-Asp-Net-4/