ASP. NET MVC file [reprint]

Source: Internet
Author: User
Tags server memory

If you only have an ASP. NET Web forms background instead of learning ASP. I think your first experience might be that server-side controls that have made your programming enjoyable have been driving the west. FileUpload is one of them, and the absence of this control brings us some minor problems. This article mainly says how to upload files in ASP. NET MVC, and then how to download the uploaded files from the server.

In Web Forms, when you drag a FileUpload control to the designer, you may not notice that an extra attribute enctype= "Multipart/form-data" is added to the form tag in the generated HTML. And the FileUpload control itself will be <input type= "file"/> in MVC view, there are many ways to do the same, the first HTML is as follows:

<Formaction="/"Method="POST"Enctype="Multipart/form-data"><input type= "file" Span style= "color: #ff0000;" >name= "FileUpload1" /> <br /> <input type= " Submit "name=" submit " Id= "Submit" value= " Upload "/></ Form>           

Note that the form label already includes the enctype tag, and the method property is set to "post", so that it does not have more than the default commit when it is done by HTTP GET. In this way, using the Html.BeginForm () extension method will generate the same HTML 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=< Span style= "color: #0000ff;" > "Upload" /><%}%                 

Note <input type= The Name property of the "file" > tag, which we'll discuss later, the code above will look like this:

OK, now we can browse the local file and then submit the file to the server through 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 see if the file is uploaded by FileUpload's HasFile method. But it doesn't seem so convenient in ASP. You'll be closer to the original HTTP, however, an extension method can handle these:

BOOL HasFile (thishttppostedfilebase file) {  false;} 

When you see the code for the corresponding controller class, you will find that the request object exists as a property of the Httprequestbase type. Httpreuqestbase is actually a package of HTTP requests, with a lot of attributes, including files collection (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 exists. In fact, this is consistent with how the Fileupload.hasfile () method works.

It's easy to use in a controller action:

Class homecontroller:controller{public  actionresult Index ()  {    foreach (string path = AppDomain.CurrentDomain.BaseDirectory + "return View ();}}   

multiple file uploads

Perhaps you have thought earlier than I how to better use Request.Files as a collection. This means that not only can it accommodate a single file, but it can accommodate multiple, we will change the view above to read as follows:

<% using (Html.BeginForm ("", "Home", FormMethod.Post, new {enctype= "Multipart/form-data"})) {%><InputType="File"Name="FileUpload1"/><Br/><InputType="File"Name="FileUpload2"/><Br/><InputType="File"Name="FileUpload3"/><Br/><InputType="File"Name="FileUpload4"/><Br/><input type= "file" name= "FileUpload5" /><br /> <input type=  "submit" name= "submit "id=" Submit "value=< Span style= "color: #0000ff;" > "Upload" /><%}%                 

The effect is as follows:

In the controller's code has checked whether all the File upload box has files, so even for multi-file upload, we no longer need to modify the controller's code, note each <input type= "file" > have different name attributes, if you need to call one, for example, you need to refer to the third input box only using: request.files["FileUpload3"].

Deposit Database

Before you howling me. "Focus Separation", I would like to declare that the following code is only used as a description feature. I put the ADO code into the controller action, but we all know that this is not good. The code for data access should be placed in the data access layer of a part of the model. However, the following code can only give you a more intuitive impression of how to store uploaded files in the database, first, we need to create a data table (Filetest) and create a table: Filestore

CREATE TABLE [dbo]. [Filestore] ([ID] [int] IDENTITY (a) not null,[filecontent] [image] not null,[mimetype] [nvarchar] (a) not null,[filename] [nvarchar ] () not NULL) on [PRIMARY] textimage_on [PRIMARY]

The Filecontent field is an image data type that stores files formed in binary data, and the index action changes to:

Public ActionResult Index () {foreach (String uploadIn Request.Files) {if (! Request.files[upload]. HasFile ())ContinueString 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 =NewByte[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, Filen AME) 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 iterates through all the uploaded files in the Web page in a loop and checks to see if the <input type= "file" > has been added to the files, and then extracts 3 messages from the file: file name, MIME type (type of file), HTTP Binary stream in Request. Binary data is converted to a byte array and stored in the database as an image data type. MIME types and filenames are important for users to extract files from the database.

To return a file from the database to the user:

How you send the file to the user depends on how you first store it, and if you save the file to the database, you will stream the file back to the user, if you have the file on the hard disk, you only need to provide a hyperlink, or you can also stream the way. Whenever you need to stream files to the browser, you use the overloads of the file () method (instead of using the view () method we have been using previously), there are 3 class return types for the file () method: Filepathresult, Filecontentresult and Filestreamresult, the first type is used to return files directly from the disk, the second type is used to return a byte array to the client, and the third method returns the contents of the stream object that has been generated and opened to the client.

If you remember, we saved the uploaded file to the database and stored it in the filecontent domain as a byte array. And when it needs to be extracted, it will still be extracted in a byte array, which means we use the file returned by Filecontentresult ( Overload, if we want to make the extracted filename more meaningful, we use an overload that accepts 3 parameters, three parameters are: byte array, MIME type, file name:

Public Filecontentresult GetFile (int id) {SqlDataReader rdr;byte[] Filecontent =NullString MimeType = "";String fileName = "";ConstString connect = @ "server=.\sqlexpress;database=filetest; Trusted_connection=true; "; using (var conn = new SqlConnection (connect)) {var qry = "select Filecontent, MimeType, FileName from FilesTo Re 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 use of this action in view is to simply provide a hyperlink:

<href="/GETFILE/1">click to get file</a>     

If the picture stored in the database is a picture type, and the hyperlink is different, we get it by pointing to a <image> tag with the SRC attribute to the controller action:

<src=alt=/>  

Let's take a look at how simple it is to use Filepathresult (to extract files from a 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 used to extract hyperlinks:

<href="/getfilefromdisk">click to get file</a>   

And the last choice Filestreamresult can also extract files from 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);}    

What is the difference between Filepathresult and Filestreamresult? What are we to 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 this is a good choice for sending large files. Their differences are much like the difference between DataReader and datasets. At the same time, TransmitFile also has a bug, which may cause the file to be sent to the client half stopped, or even unable to transfer. And Filestreamresult is great in this respect. For example: Returns the chart picture that the ASP. NET chart control generates in memory, which does not require that the picture be saved to disk.

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.