Asp.net implementation MVC file upload and download function example tutorial

  • 2021-01-19 22:12:59
  • OfStack

Upload to download function is a very common function in the program design, in ASP.NET program development has a very wide range of applications. This paper is to achieve this function in the form of an example.

1. An overview of the

If you only have Asp.net, Web, Forms and move on to Asp.net, MVC, I think your first experience will be that all the server-side controls that once made your programming so enjoyable are gone. Asp.net. MVC.net. MVC.net. MVC.

2. Implementation method

1. File upload

In Web, when you drag an FileUpload control into the designer, you may not notice that an extra attribute is added to the form tag in the generated HTML, enctype="multipart/form-data". The ES33en control itself is generated as < input type file = "/" > In MVC view, there are many kinds of ways to achieve the same effect, 1 kind of HTML is as follows:


<form action="/" method="post" enctype="multipart/form-data"> 
 <input type="file" name="FileUpload1" /><br /> 
 <input type="submit" name="Submit" id="Submit" value="Upload" /> 
</form> 

Note that the form tag already includes the enctype tag, and the method attribute is set to "post", which is no more than the default submission via HTTP and get. The following method, using the Html.BeginForm () extension method, produces the same ES53en as above:


<% 
 using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
  {%>  
   <input type="file" name="FileUpload1" /><br /> 
   <input type="submit" name="Submit" id="Submit" value="Upload" /> 
<% }%> 

Pay attention to < input type file = "" > The name attribute of the tag is discussed later
OK, now we can browse the local file and submit the file to the server via the Upload submit button. The next step is to process the uploaded file on the server side. When using the fileUpload control, you can easily check whether the file has been uploaded by using the hasFile method of FileUpload. In ES69en. ES70en ES71en, however, it is not so convenient. You will be closer to the original ES72en. However, an extension method can handle this:


public static bool HasFile(this HttpPostedFileBase file) 
{ 
 return (file != null && file.ContentLength > 0) ? true : false; 
}

When you look at the code for the corresponding ES76en class, you will see that the ES77en object exists as a property of type ES78en. HttpReuqestBase is an encapsulation of HTTP requests, which contains a number of attributes, including Files collection (which is actually a collection of HttpFileCollectionBase). Each element in the collection is a collection of HttpPostedFileBase, and the extension method is used to ensure that the uploaded file does not exist. In fact, this is similar to how the FileUpload.HasFile () method works.

It's actually quite easy to use in Controller Action:


public class HomeController : Controller 
{ 
 public ActionResult Index() 
 { 
  foreach (string upload in Request.Files) 
  { 
   if (!Request.Files[upload].HasFile()) continue; 
   string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; 
   string filename = Path.GetFileName(Request.Files[upload].FileName); 
   Request.Files[upload].SaveAs(Path.Combine(path, filename)); 
  } 
  return View(); 
 } 
}

2. Multiple file uploads

Perhaps you have figured out before me how to use ES96en. ES97en as a collection. This means that it can hold not only one file, but multiple files. We changed the View above to the following:


<% 
 using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
  {%>  
   <input type="file" name="FileUpload1" /><br /> 
   <input type="file" name="FileUpload2" /><br /> 
   <input type="file" name="FileUpload3" /><br /> 
   <input type="file" name="FileUpload4" /><br /> 
   <input type="file" name="FileUpload5" /><br /> 
   <input type="submit" name="Submit" id="Submit" value="Upload" /> 
<% }%>  

The Controller code has checked to see if all the file upload boxes have files, so even for multiple file uploads, we don't need to change the Controller code any more, pay attention to each one < input type file = "" > All have different name attributes. If you need to call one of them, for example, you need to refer to a third input field just use: Request.Files ["FileUpload3"].

3. Store in a database

Before you scream "separation of concerns" at me, I want to state that the following code is for illustrative purposes only. I put the code for ADO.Net in Controller action, but as we all know, this is not good. The data access code should be in the data access layer in some part of Model. However, the following code only gives you a more visual impression of how to upload files to the database. First, we need to create a table (FileTest) and create a table :FileStore


CREATE TABLE [dbo].[FileStore]( 
[ID] [int] IDENTITY(1,1) NOT NULL, 
[FileContent] [image] NOT NULL, 
[MimeType] [nvarchar](50) NOT NULL, 
[FileName] [nvarchar](50) NOT NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

The FileContent domain is the image data type, which is used to store files formed in binary data, and the Index Action domain is:


public ActionResult Index() 
{ 
 foreach (string upload in Request.Files) 
 { 
  if (!Request.Files[upload].HasFile()) continue; 
  string mimeType = Request.Files[upload].ContentType; 
  Stream fileStream = Request.Files[upload].InputStream; 
  string fileName = Path.GetFileName(Request.Files[upload].FileName); 
  int fileLength = Request.Files[upload].ContentLength; 
  byte[] fileData = new byte[fileLength]; 
  fileStream.Read(fileData, 0, fileLength); 
  const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;"; 
  using (var conn = new SqlConnection(connect)) 
  { 
   var qry = "INSERT INTO FileStore (FileContent, MimeType, FileName) VALUES (@FileContent, @MimeType, @FileName)"; 
   var cmd = new SqlCommand(qry, conn); 
   cmd.Parameters.AddWithValue("@FileContent", fileData); 
   cmd.Parameters.AddWithValue("@MimeType", mimeType); 
   cmd.Parameters.AddWithValue("@FileName", fileName); 
   conn.Open(); 
   cmd.ExecuteNonQuery(); 
  } 
 } 
 return View(); 
}

The modified code loops through all the uploaded files in the Web page and checks < input type file = "" > Then, extract three pieces of information from the file: the file name, MIME type (the type of file), and the binary stream in HTTP Request. The binary data is converted to an byte array and stored in the database as an image data type. The MIME type and file name are important for users to extract files from the database.

Return file from database to user:

How you send the file to the user depends on how you store it in the first place. If you store the file in a database, you'll stream the file back to the user. If you store the file on hard drive, you only need to provide a hyperlink, or you can stream it. Whenever you need to stream a file to the browser, you use the overloading of the File() method (instead of the View() method we used earlier). There are three types of return types for the File() method: FilePathResult,FileContentResult, and FileStreamResult. The second type is used to return the byte array to the client; The third method returns the content of the stream object that has been generated and opened to the client.

If you remember, the uploaded files were stored in the database as an byte array in the FileContent field. When we need to extract it, it will still extract as an array of byte, which means we use the File() overload that returns FileContentResult. If we want to make the extracted filename more meaningful, we use the overload that takes 3 arguments :byte array, MIME type, filename:


public FileContentResult GetFile(int id) 
{ 
 SqlDataReader rdr; byte[] fileContent = null;  
 string mimeType = "";string fileName = ""; 
 const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;"; 
 using (var conn = new SqlConnection(connect)) 
 { 
  var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID"; 
  var cmd = new SqlCommand(qry, conn); 
  cmd.Parameters.AddWithValue("@ID", id); 
  conn.Open(); 
  rdr = cmd.ExecuteReader(); 
  if (rdr.HasRows) 
  { 
   rdr.Read(); 
   fileContent = (byte[])rdr["FileContent"]; 
   mimeType = rdr["MimeType"].ToString(); 
   fileName = rdr["FileName"].ToString(); 
  } 
 } 
 return File(fileContent, mimeType, fileName); 
}  

The simplest way to use this View is to provide 1 hyperlink:


<a href="/GetFile/1">Click to get file</a> 

If the image stored in the database is an image type, instead of using a hyperlink, we point to one of Controller's action attributes by pointing to src < image > Tag to get:


<img src="/GetFile/1" alt="My Image" /> 

Let's take a look at how easy it is to use FilePathResult (for extracting files from hard disk) :


<% 
 using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
  {%>  
   <input type="file" name="FileUpload1" /><br /> 
   <input type="submit" name="Submit" id="Submit" value="Upload" /> 
<% }%> 

0

This can also be extracted using hyperlinks:


<% 
 using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
  {%>  
   <input type="file" name="FileUpload1" /><br /> 
   <input type="submit" name="Submit" id="Submit" value="Upload" /> 
<% }%> 

1

The last option, FileStreamResult, can also extract files from disk:


<% 
 using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))  
  {%>  
   <input type="file" name="FileUpload1" /><br /> 
   <input type="submit" name="Submit" id="Submit" value="Upload" /> 
<% }%> 

2

Added 3.

What is the difference between FilePathResult and FileStreamResult? And how do we choose? The main difference is that FilePathResult uses HttpResponse.TransmitFile to write files to the Http output stream. This method does not buffer in server memory, so it is a good choice for sending large files. The difference is much like the difference between DataReader and DataSet. At the same time, TransmitFile still has 1 bug, which may cause the file to stop halfway to the client, or even cannot be transferred. The FileStreamResult is great for that. Asp.net The Chart control generates a chart image in memory, which does not require the image to be saved to disk.


Related articles: