I have written an article on the ASP.NET method about
how to download documents from a database (Traditional Chinese); however, there are some defects as a result of this method. For example, because of the binary file, it takes up a huge space of the database, even after zipping the documents. Moreover, if your framework is separated into web application and database servers, the bandwidth and I/O costs will grow.
Let’s do this in a different way; upload a file to Web Application under a specific folder. Then, save this information to the database. This information is text, so it won’t impact the efficiency of the database server. Even if you have billions of records, your database will still work efficiently. When you need to download a document (file), your query information from the database will map to the specific folder (file) and respond to the client browser.
Based on the ASP.NET MVC implement, it will contain two parts: one is single file upload, one is the multi-file upload.
DataBase Schema
I create a new file in the App_Data in Files.mdf, table name called FileDown, and table Schema is:
FileId, int, PK
FileName, nvarchar(50)
FileSize, nvarchar(50)
FileType, nvarchar(50)
FileVersion, nvarchar(50)
PostDate, datetime2(7)
UploadDate, datetime2(7)
rowguid, uniqueidentifier
In the Models folder, I create FileModel.edmx and FileModel.Context.tt, FileModel.tt. (Entity Framework 4.1)
ASP.NET MVC - Single File Upload
Create a New FileController.vb and write down our architecture.
Controller and Action : fileController.vb
Imports System.IO
Public Class fileController
Inherits System.Web.Mvc.Controller
' File Lists
Function Index() As ActionResult
Return View()
End Function
' Single File Upload
Function Upload() As ActionResult
Return View()
End Function
' Single File Save
<HttpPost()>
Function Upload(upfile As HttpPostedFileBase, formData As FormCollection) As ActionResult
Return View()
End Function
' Multi-File Upload
Function MultiUpload() As ActionResult
Return View()
End Function
' Multi-File Save
<HttpPost()>
Function MultiUpload(form As FormCollection) As ActionResult
Return View()
End Function
' File Download
Function Download(id As Integer) As ActionResult
Return View()
End Function
End Class
We work step by step.
Action:Index
' File Lists
Function Index() As ActionResult
Dim db As New FilesEntities
Return View(db.FileDown)
End Function
View : Index.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of UpDownFileFromDBMvc.FileDown))" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
File Lists
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>File Lists</h2>
<ul>
<li><%: Html.ActionLink("Single File Upload", "Upload")%></li>
<li><%: Html.ActionLink("Multi-File Upload", "MultiUpload")%></li>
</ul>
<table>
<tr>
<th>
FileId
</th>
<th>
FileName
</th>
<th>
FileSize
</th>
<th>
FileType
</th>
<th>
FileVersion
</th>
<th>
PostDate
</th>
<th>
UploadDate
</th>
<th>
rowguid
</th>
</tr>
<% For Each item In Model %>
<% Dim currentItem = item %>
<tr>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.FileId) %>
</td>
<td>
<%: Html.ActionLink(currentItem.FileName, "download", New With {.id = currentItem.FileId})%>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.FileSize) %>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.FileType) %>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.FileVersion) %>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.PostDate) %>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.UploadDate) %>
</td>
<td>
<%: Html.DisplayFor(Function(modelItem) currentItem.rowguid) %>
</td>
</tr>
<% Next %>
</table>
</asp:Content>
We should notice that there is <%: Html.ActionLink(currentItem.FileName, "download", New With {. Id = currentItem.FileId})%>. After uploading, we hope to click the file name and download the file directly, so we have the DisplayFor() rewritten toHtml.ActionLink().
Action:Upload
''' <summary>
''' ASP.NET MVC Single File Upload
''' </summary>
''' <param name="upfile">Upload file</param>
''' <param name="formData">Other file data</param>
<HttpPost()>
Function Upload(upfile As HttpPostedFileBase, formData As FormCollection) As ActionResult
Using db As New FilesEntities
If upfile IsNot Nothing Then
' 0 < Size < 4 MB
Dim MBSize As Integer = upfile.ContentLength / 1000 / 1000
If upfile.ContentLength > 0 AndAlso MBSize < 4 Then
Dim savePath As String = Path.Combine(Server.MapPath("~/Files/"), upfile.FileName)
' Only *.7z file name
If Path.GetExtension(savePath) <> ".7z" Then
ModelState.AddModelError("upfile", "File name only *.7z!")
Return View()
End If
' Date Check
If IsDate(formData("PostDate")) = False Then
ModelState.AddModelError("PostDate", "Date Format Is Error!")
Return View()
End If
' Version Check
If formData("FileVersion") = "" Then
ModelState.AddModelError("FileVersion", "Must have file version!")
Return View()
End If
' Uploading
If System.IO.File.Exists(savePath) = False Then
' Database Checking
Dim FileDuplicate As FileDown = (From f In db.FileDown
Where (f.FileName = upfile.FileName)
Select f).FirstOrDefault()
' File name checking
If FileDuplicate Is Nothing Then
' Save to Disk
upfile.SaveAs(savePath)
' Set File Information
Dim file As New FileDown
file.FileName = upfile.FileName
file.FileSize = upfile.ContentLength
file.FileType = upfile.ContentType
file.PostDate = formData("PostDate")
file.FileVersion = formData("FileVersion")
file.UploadDate = Date.Now()
file.rowguid = Guid.NewGuid()
' File Information Save to Database
db.FileDown.Add(file)
db.SaveChanges()
Else
ModelState.AddModelError("upfile", "Database have same file information!")
Return View()
End If
Else
ModelState.AddModelError("upfile", "File exist!")
Return View()
End If
End If
End If
End Using
Return RedirectToAction("Index")
End Function
We create a
Files folder in the project to store uploaded files.
Here we should notice that the parameters passed in sequential order, Upload.aspx order form, if the upload file field first, then upfile As HttpPostedFileBase necessary in the first, and vice versa.
View:Upload.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Upload Single File
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Upload Single File</h2>
<%Using Html.BeginForm("Upload", "file", FormMethod.Post, New With {.enctype = "multipart/form-data"})%>
<%: Html.ValidationSummary(True)%>
File:<input id="upfile" name="upfile" type="file" value="" />
<%: Html.ValidationMessage("upfile")%>
PostDate:<%: Html.TextBox("PostDate")%>
<%: Html.ValidationMessage("PostDate")%>
Version:<%: Html.TextBox("FileVersion")%>
<%: Html.ValidationMessage("FileVersion")%>
<input type="submit" value="Upload" />
<%End Using%>
</asp:Content>
ASP.NET MVC Multi-File Upload
Next let’s take a look at the multi-file uploads.
Action:MultiUpload
''' <summary>
''' ASP.NET MVC Multi-File Upload
''' </summary>
''' <param name="form">form data</param>
<HttpPost()>
Function MultiUpload(form As FormCollection) As ActionResult
' Data Check Reference "Action:Upload"
Dim Msg As String = String.Empty
For i As Integer = 0 To Request.Files.Count - 1
Msg += Request.Files(i).FileName & " Upload succeed!"
Request.Files(i).SaveAs(Server.MapPath("~/Files/") & Request.Files(i).FileName)
Next
ViewBag.Msg = MvcHtmlString.Create(Msg)
Return View()
End Function
Let me skip some steps, check the files and add information to the database are almost the same with we have mentioned above. Now you try to do it yourself.
View:MultiUpload.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Multi-File Upload
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Multi-File Upload</h2>
<%: Html.ActionLink("Go back Index","Index") %>
<% Using (Html.BeginForm("MultiUpload", "File", FormMethod.Post, New With {.enctype = "multipart/form-data"}))%>
<div class="uploadfiles">
<p>
<input type="file" name="files" />
</p>
</div>
<p>
<a href="#add" id="additem">Add Upload File</a>
<input type="submit" value="Upload" />
</p>
<% End Using%>
<%: ViewBag.Msg %>
<script type="text/javascript">
$('#additem').live('click', function () {
$('.uploadfiles').append($("<p><input type='file' name='files' /></p>"));
});
</script>
</asp:Content>
The most important part is the bellowing jQuery, let us re-state to upload new data fields.
ASP.NET MVC File Download
The last download program.
Action:Download
Function Download(id As Integer) As ActionResult
Using db As New FilesEntities
' Get file information
Dim getfile = (From f In db.FileDown
Where f.FileId = id
Select f).FirstOrDefault()
If getfile.FileName IsNot Nothing Then
Dim FilePath As String = Server.MapPath("~/Files/" & getfile.FileName)
' downloading
If System.IO.File.Exists(FilePath) Then
Return File(FilePath, getfile.FileType, getfile.FileName)
End If
Else
' response error
Return Content("<span style='color:red'>Can't download file!</span>")
End If
End Using
Return RedirectToAction("Index")
End Function
We design a table with
GUID, you can also use the GUID to design a method for users to download, so users can not guess easily like 1,2,3,4 number to download data.
ASP.NET MVC File Delete
Skip some steps for you to write here.
- Query the id from the database to find the file name.
- Use Path.Combine and Server.MapPath () to combine the full path.
- Use File.Exists (path) to determine whether the file exists.
- If it exists, delete files and database information.(File.Delete (path))
Now an uploading, downloading, deleting, simple file management program is completed.