Asp.net implements the MVC file upload/download function example tutorial, mvc upload/download

Source: Internet
Author: User
Tags server memory

Asp.net implements the MVC file upload/download function example tutorial, mvc upload/download

The upload/download function is a very common feature in programming. It is widely used in ASP. NET program development. This article uses instances to implement this function.

I. Overview

If you only have the background of Asp.net Web Forms and want to learn Asp.net MVC, I think your first experience may be the server-side controls that once made your programming very pleasant. fileUpload is one of them, and the absence of this control brings us some minor problems. This article mainly describes how to upload files in Asp.net MVC and then download uploaded files from the server.

II. Implementation Method

1. File Upload

In Web Forms, when you drag a FileUpload control to the designer, you may not notice that an additional attribute enctype = "multipart/form-data" will be added to the form tag in the generated HTML ". the FileUpload control itself is generated as <input type = "file"/>. In the MVC view, there are many ways to achieve the same effect. The first type 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 label already includes the enctype label, and the method attribute is set to "post". This setting is not more than that of the default submission through HTTP get. In the following method, the Html. BeginForm () extension method will generate the same HTML as the 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" /> <% }%> 

Note that the name attribute of the <input type = "file"> tag will be discussed later.
OK. Now we can browse the local file and submit the file to the server through the Upload submit button. The next step is to process the uploaded file on the server. When using the fileUpload control, you can easily use the hasFile method of FileUpload to check whether the file is uploaded. However, in Asp.net MVC, it seems that it is not so convenient. You will be closer to the original HTTP. However, an extension method can handle this:

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

When you see the corresponding Controller class code, you will find that the Request object exists as an attribute of the HttpRequestBase type. HttpReuqestBase is actually an encapsulation of HTTP requests, which exposes many attributes, including Files collection (which is actually a collection of HttpFileCollectionBase). Every element in the collection is a collection of HttpPostedFileBase, the extension method is used to ensure that the uploaded file exists. In fact, this is consistent with the working principle of the FileUpload. HasFile () method.

It is actually easy to use in Controller actions:

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. Multifile upload

Maybe you have thought of how to better use Request. Files as a collection earlier than I did. This means that it can accommodate not only one file, but more than one. We will change 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 checks whether all file upload boxes contain files. Therefore, even for multi-file uploads, we do not need to modify the Controller code, note that each <input type = "file"> has different name attributes. If you need to call one of them, for example, you only need to use Request to reference the third input box. files ["FileUpload3"].

3. Save to database

Before you yell at me for separation of focus, I want to declare that the following code is only used as a description function. I will add ADO. net code into the Controller action, but we all know that this is not good. The data access code should be placed in the data access layer of a certain part of the Model. however, the following code only gives you a more intuitive impression on how to store uploaded files to the database. First, we need to create a data 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 field is of the image data type and is used to store files formed by binary data. The Index Action is changed:

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 traverses all uploaded files on the Web page in a circular manner, and checks whether the file has been added to <input type = "file">. Then, extract three pieces of information from the file: file name, MIME type (file type), and binary stream in HTTP Request. Binary data is converted to a byte array and stored in the database as an image. MIME types and file names are very important for users to Extract files from the database.

4. Return the files in the database to the user:

How you transmit a file to a user depends on how you store it at the beginning. If you store the file in the database, you will return the file to the user through a stream, if you store a file in a hard disk, you only need to provide a hyperlink, or you can stream the file. Every time you need to stream the File to the browser, you use the File () method overload (instead of using the View () method we have been using ), there are three types of return types for the File () method: FilePathResult, FileContentResult and FileStreamResult. The first type is used to directly return files from the disk; the second type is used to return byte arrays to the client; the third method returns the content of the generated and opened Stream object to the client.

If you still remember, we saved the uploaded files to the database and saved them to the FileContent domain in the form of byte arrays. when the extraction is required, it will still be extracted using a byte array, which means that we use the File () reload that returns FileContentResult. If we want to make the extracted File name more meaningful, we use the overload that accepts three parameters. The three parameters are byte array, MIME type, and file name:

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); }  

You only need to provide a hyperlink for the simplest use of this Action in View:

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

If the image stored in the database is of the image type, unlike the hyperlink, we can obtain the image by pointing to a <image> tag with the src attribute of the Controller action:

 

Next let's take a look at how simple it is to use FilePathResult (used to extract files from the hard disk:

public FilePathResult GetFileFromDisk() {  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";  string fileName = "test.txt";  return File(path + fileName, "text/plain", "test.txt"); }  

This can also be extracted using hyperlinks:

<a href="/GetFileFromDisk">Click to get file</a> 

The last selected FileStreamResult can also Extract files from the disk:

public FileStreamResult StreamFileFromDisk() {  string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";  string fileName = "test.txt";  return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName); }  

Iii. Supplement

What is the difference between FilePathResult and FileStreamResult? How can we choose between them? The main difference is that FilePathResult uses HttpResponse. TransmitFile to write the file to the Http output stream. This method does not buffer in the server memory, so it is a good choice for sending large files. Their differences are similar to those of DataReader and DataSet. At the same time, TransmitFile also has a bug, which may cause the file to stop when it is uploaded to the client in half, or even fail to be transmitted. FileStreamResult is great in this regard. For example, if you return the Chart image generated by the Asp.net Chart control in the memory, you do not need to save the image to the disk.


To learn how aspnet can upload and download files, it is best to provide detailed source code.

Upload: HttpPostedFile postFile = Upload. PostedFile; postFile. SaveAs (MapPath ("path "));
Download:
Public static void DownLoadFile (string path)
{
Path = HttpContext. Current. Server. MapPath (path );
System. IO. FileInfo file = new System. IO. FileInfo (path );
HttpContext. Current. Response. Clear ();
HttpContext. Current. Response. AddHeader ("Content-Disposition", "attachment; filename =" + HttpUtility. UrlEncode (file. Name ));
HttpContext. Current. Response. AddHeader ("Content-Length", file. Length. ToString ());
HttpContext. Current. Response. ContentType = "application/octet-stream ";
HttpContext. Current. Response. WriteFile (file. FullName );
HttpContext. Current. Response. End ();
}

Aspnet mvc20 uploading multiple files

For (fileCount = 0; fileCount <files. Count; fileCount ++)
{
// Define the object for accessing the client to upload files
System. Web. HttpPostedFile postedFile = files [fileCount];
String FileType = postedFile. ContentType. ToString (); // obtain the file type to be uploaded and verify the file header.

String fileName, fileExtension;
// Get the uploaded file name
FileName = System. IO. Path. GetFileName (postedFile. FileName );
// Get the file extension
FileExtension = System. IO. Path. GetExtension (fileName );

// When the file to be uploaded is not empty, verify that the file name and size are consistent. If not, upload is not allowed.
If (FileType = "text/plain" & fileExtension. toLower () = ". txt ") | (FileType =" application/x-zip-compressed "& fileExtension. toLower () = ". zip ") | (FileType =" application/octet-stream "& fileExtension. toLower () = ". rar ") & postedFile. contentLength/1024 <= 1024)
{// Check whether the file header matches the file name to limit the File Upload type. Note: The File Upload types include TXT, ZIP, and RAR, and the file size can only be 1 MB.

If (fileName! = String. Empty)
{
FileName = RandomFileName () + fileExtension;

// Upload File Information
StrMsg. Append ("type of the uploaded file:" + postedFile. ContentType. ToString () + "<br> ");
StrMsg. Append ("client file address:" + postedFile ...... remaining full text>

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.