2017年7月22日 星期六

ASP.NET 利用JavaScript達到多檔上傳

這是大學時期的畢業專題,曾經寫過的一個「多檔上傳」的功能,參考國外的文章,至於那篇文章,我也沒特別留下來,今天特別找出來記錄,以防哪一天需要用的時候就可以使用,這也是大學時期對一個剛學程式的學生來講,特別有成就感的一個功能;在這裡還是要提一下檔案上傳可能會影響的資安問題(ASP.NET FileUpload上傳檔案,讀取Byte檢查副檔名,以圖片為例)。

執行結果

Step 1.先設定Web.config
<configuration>
    <system.web>
      <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
      <!-- 可修改maxRequestLength的值來改變上傳限制,單位為K,4096=4MB,15360=15MB -->
      <httpRuntime maxRequestLength="15360"/>
    </system.web>
</configuration>

Step 2.test_multi-file_fileupload.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test_multi-file_fileupload.aspx.vb" Inherits="test_multi_file_fileupload" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
        function addFileUploadBox() {
            if (!document.getElementById || !document.createElement) {
                return false;
            };
            //取得id叫作upload-area元素
            var uploadArea = document.getElementById('upload-area');
            if (!uploadArea) {
                return false;
            };
            //建立br元素(在Html中叫作換行)
            var newLine = document.createElement('br');
            //在upload-area中加入換行
            uploadArea.appendChild(newLine);
            //建立input元素
            var newUploadBox = document.createElement('input');
            newUploadBox.type = 'file'; //input的類型為file檔案類型
            newUploadBox.size = '40';
            if (!addFileUploadBox.lastAssignedId) {
                addFileUploadBox.lastAssignedId = 100;
            };
            //設定input的id、name
            newUploadBox.setAttribute('id', 'FileF' + addFileUploadBox.lastAssignedId);
            newUploadBox.setAttribute('name', 'FileF:' + addFileUploadBox.lastAssignedId);
            uploadArea.appendChild(newUploadBox);
            addFileUploadBox.lastAssignedId++;
        };
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>測試多檔上傳</h1>
        附加檔案:<br/>
        <p id="upload-area">
            <input id="FileField" type="File" runat="server" size="40" />
        </p>
        <input id="ButtonAdd" type="button" value="繼續附加" onclick="addFileUploadBox();" />&nbsp;&nbsp;
        <asp:Button ID="Button1" runat="server" Text="開始上傳" /><span style=" color:red;">檔案附加不可超過10MB</span><br/>
        <asp:Label ID="Send_msg" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

Step 3.test_multi-file_fileupload.aspx.vb
Imports System.IO
Partial Class test_multi_file_fileupload
    Inherits System.Web.UI.Page

    Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '======================
        Dim uploads As HttpFileCollection = Nothing
        uploads = HttpContext.Current.Request.Files
        Dim FileToUpload As HttpPostedFile = Nothing
        '======================
        '計算全部附加檔案的大小
        Dim x_KB As Integer = 0, x_Byte As Integer = 0
        Dim x_MB As Double
        For i As Integer = 0 To (uploads.Count - 1)
            FileToUpload = uploads(i)
            x_Byte = x_Byte + FileToUpload.ContentLength
        Next
        x_KB = x_Byte / 1024 'Byte / 1024=KB
        x_MB = x_KB / 1024 'KB / 1024=MB
        '信件傳送不能超過或等於10MB
        If Int(x_MB) >= 10 Then '取整數
            '否則>=10MB
            '所有的附加檔案不能超過或等於10MB
            Send_msg.Text = "注意:所有的附加檔案加起來不能超過或等於10MB"
            Send_msg.ForeColor = Drawing.Color.Red
            Exit Sub
        End If
        '======================
        Dim us_f As UShort = 0 '檔案是否重複,重複為1,不重複0
        Dim str_FolderName As String = "File"
        Dim GEM_MSG As New StringBuilder
        Dim FilePath() As String = Nothing '存放檔案路徑
        Dim AYN As Integer = -1
        For i As Integer = 0 To (uploads.Count - 1)
            FileToUpload = uploads(i)
            ReDim Preserve FilePath(i)
            If FileToUpload.FileName <> "" Then
                AYN = AYN + 1
                '建立檔案路徑
                '第三個參數:指定看由哪一個網頁呼叫此程序,就必須在那個目錄下建立資料夾
                FilePath(i) = ServerFilePath(FileToUpload, System.IO.Path.GetFileName(FileToUpload.FileName), str_FolderName) '串聯路徑
                '===============================
                Dim FileName As String = Nothing

                If (FileToUpload.ContentLength <> 0) Then
                    'System.IO.Path.GetFileNameWithoutExtension(FileToUpload.FileName) '取檔案名稱,不包含副檔名
                    'System.IO.Path.GetExtension(FileToUpload.FileName) '取副檔名
                    '判斷檔案名稱是否有重複
                    If File.Exists(FilePath(i)) = True Then
                        Dim Uploadfile As String
                        Uploadfile = HttpContext.Current.Server.MapPath(str_FolderName) '會指定看由哪一個網頁呼叫此程序,就必須在那個目錄下建立資料夾
                        Dim Repeat_Number As Integer = 0
                        While (File.Exists(FilePath(i)))
                            Repeat_Number = Repeat_Number + 1
                            '如果存在就更改檔名
                            FileName = System.IO.Path.GetFileNameWithoutExtension(FileToUpload.FileName) & "(" & Repeat_Number & ")" &
                            System.IO.Path.GetExtension(FileToUpload.FileName)
                            FilePath(i) = Uploadfile + "\" + FileName
                        End While
                        GEM_MSG.Append("<span style=" & Chr(34) & "color:red;" & Chr(34) & ">附加檔案名稱以重複,檔案名稱修改為" & FileName)
                    Else
                        GEM_MSG.Append("<span style=" & Chr(34) & "color:blue;" & Chr(34) & ">" & System.IO.Path.GetFileName(FileToUpload.FileName))
                    End If
                End If
                Try
                    FileToUpload.SaveAs(FilePath(i))
                    GEM_MSG.Append(",附加成功</span><br />")
                Catch ex As Exception
                    GEM_MSG.Append(",附加失敗</span><br />")
                    'GEM_MSG.Append(",附加失敗" & ex.ToString & "</span><br />")
                End Try
                '===============================
            Else
                FilePath(i) = ""
            End If
            If i = uploads.Count - 1 And AYN <> -1 Then
                GEM_MSG.Append("<hr size=" & Chr(34) & "1" & Chr(34) & " />")
            End If
        Next
        Send_msg.Text = GEM_MSG.ToString
        Send_msg.ForeColor = Drawing.Color.Black

    End Sub

    '建立檔案路徑,
    Function ServerFilePath(ByVal FileToUpload As HttpPostedFile, ByVal FileName As String, ByVal Folder_name As String) As String

        Dim Uploadfile As String
        Uploadfile = HttpContext.Current.Server.MapPath(Folder_name) '會指定看由哪一個網頁呼叫此程序,就必須在那個目錄下建立資料夾
        If Directory.Exists(Uploadfile) = False Then '檢查目錄存不存在
            '不存在就建立資料夾
            Directory.CreateDirectory(Uploadfile)
        End If
        If (FileToUpload.ContentLength <> 0) Then
            Uploadfile = Uploadfile + "\" + FileName '建立檔案路徑
        Else
            Uploadfile = ""
        End If
        Return Uploadfile
    End Function
End Class



沒有留言:

張貼留言