檔案上傳一直是教書以來想要完成的事,可是大部分的書都叫讀者上傳到伺服器的某個資料夾儲存,這會是一個嚴重的問題。這學期教資料庫剛好複習一下,這次使用Visaul Studio 2010,是 ASP.NET 4.0,應該可以用個幾年吧。
1. 首先在設計模式布置FileUpload(負責選取檔案), textbox(負責輸入檔案描述,可空白),Button(負責驅動上傳), Literal(負責上傳後顯示資訊),而Label物件可以不用放。
而對應要儲存檔案的資料表設計如下, fcontent負責儲存檔案內容,ftype負責檔案類型,fsize檔案大小,fname檔案全名(包括附檔名),fext負責附檔名,fdesc是檔案的描述說明, fuploadtiem存上傳的日期時間。
而程式碼uploadfile.aspx.vb的內容如下
Imports System.Data.SqlClient
Imports System.Web.Configuration
Imports System.IO
Partial Class Default4
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Dim icnt As Integer = 0, jcnt As Integer = 0
Dim sqlstring As String = "", merr As String = ""
Dim fname As String = "", fext As String = "", ftype As String = "", fsize As Integer = 0, fdesc As String = "", fuploadtime As DateTime = DateTime.Now
'處理上傳檔案、說明及檔案內容存入資料庫
Using sql_conn As New SqlConnection(WebConfigurationManager.ConnectionStrings("APPSYSConnectionString").ConnectionString)
sql_conn.Open()
Using sql_command As New SqlCommand()
'儲存檔案
'For icnt = 1 To Request.Files.Count
Dim fu_file As FileUpload = DirectCast(Page.FindControl("fu_file"), FileUpload)
Dim tb_file As TextBox = DirectCast(Page.FindControl("tb_file"), TextBox)
If fu_file.HasFile Then
jcnt = jcnt + 1
fname = fu_file.FileName
fext = Path.GetExtension(fname).ToString()
fsize = fu_file.PostedFile.ContentLength
Response.Write(fsize)
If fsize > 1024000 Then
merr = "檔案超過1MB"
End If
ftype = fu_file.PostedFile.ContentType
fdesc = tb_file.Text.Trim()
'檔案存入資料庫
sqlstring = "insert into 學生證照2 " & "(fname, fext, ftype, fsize, fdesc, fcontent, fuploadtime)"
sqlstring &= " values (@fname, @fext, @ftype, @fsize, @fdesc, @fcontent, @fuploadtime)"
sql_command.Parameters.Clear()
sql_command.CommandText = sqlstring
sql_command.Connection = sql_conn
sql_command.Parameters.AddWithValue("fname", fname)
sql_command.Parameters.AddWithValue("fext", fext.ToLower())
sql_command.Parameters.AddWithValue("ftype", ftype)
sql_command.Parameters.AddWithValue("fsize", fsize)
sql_command.Parameters.AddWithValue("fdesc", fdesc)
'fuploadtime是以client的系統時間為準
sql_command.Parameters.AddWithValue("fuploadtime", fuploadtime)
sql_command.Parameters.AddWithValue("fcontent", fu_file.FileBytes)
If merr = "" Then
sql_command.ExecuteNonQuery()
End If
Else
merr = "沒有選擇任何上傳的檔案!"
End If
' Next
End Using
End Using
'msg_close()呼叫寫在aspx的javascript副程式,javascript必須寫在<head>與</head>中間
'為了減少複雜性,我將msg_close()的指令去掉了
If merr <> "" Then
'顯示錯誤訊息
lt_show.Text = "<script language=javascript>alert(""" & merr & """);</script>"
Else
'完成上傳,返回瀏覽頁
lt_show.Text = "<script language=javascript>alert(""資料上傳完成!\n"");location.replace(""filedelete_download.aspx"");</script>"
'lt_show.Text &= "location.replace(""Default5.aspx"");</script>"
End If
End Sub
End Class
另外要一提的是預設上傳檔案有大小限制,經過測試約在4MB左右,
因此在web.config <system.web>與 </system.web>之間,加上此行程式(改變上限為10MB) <httpRuntime maxRequestLength="10240"/>
如果超過10MB,瀏覽器的畫面會出現無法顯示網頁
為了避免此畫面,所以網頁可以允許上傳<1MB的檔案,但因為原本uploadfile.aspx.vb中,有小於1MB的條件
If fsize > 1024000 Then
merr = "檔案超過1MB"
End If
除了檔案大小外,也可透過限制使用者上傳檔案的附檔名來避免發生太大的檔案,可以google查到使用java script來限制,將原本uploadfile.aspx的html修改,從原本
<asp:FileUpload ID="fu_file" runat="server" /> 改成
<asp:FileUpload ID="fu_file" runat="server" onchange="return checkFileExtension(this);"/>
此外,將下列指令放在 uploadfile.aspx 原始檔<head>與</head>中,
<script type="text/javascript">
function checkFileExtension(elem) {
var filePath = elem.value;
if (filePath.indexOf('.') == -1) {
remove(elem);
alert('不正確的副檔名格式');
return false;
}
var validExtensions = new Array();
var ext = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase();
//限制只能選取那些副檔名
validExtensions[0] = 'jpg';
validExtensions[1] = 'pdf';
validExtensions[2] = 'doc';
validExtensions[3] = 'docx';
validExtensions[4] = 'jpeg';
for (var i = 0; i < validExtensions.length; i++) {
if (ext == validExtensions[i])
return true;
}
remove(elem);
alert('不正確的副檔名格式: ' + ext.toUpperCase());
return false;
}
function remove(control) {
var who = control;
who.value = "";
var who2 = who.cloneNode(false);
who2.onchange = who.onchange;
who.parentNode.replaceChild(who2, who);
}
</script>
沒有留言:
張貼留言