Mvc&webform Control Study: File download

Source: Internet
Author: User

After the file upload in WebForm and MVC, you have to say that the user downloaded the resources from the server side. So today it's about how file downloads are implemented in WebForm and MVC. Speaking of WebForm file upload, Codeshark in his blog ASP. NET implementation file download in the 4 ways to download the file in ASP. Of course the article mainly refers to the way of realization in WebForm. summed up quite in place, then this article, first of all, look at the way the file upload in MVC. Then go back and look at the correlation of how they are implemented.

File download in Part 1 MVC

In MVC, Microsoft encapsulates the many implementations of ActionResult, which allows us to flexibly select the results of operations to respond to user actions. One important implementation of this is the Fileresult in the. NET Framework 4.0. It represents a base class that is used to send the contents of a binary file to a response. There are three implementations of the Fileresult class: Filecontentresult, Filestreamresult, Filepathresult. The file download in MVC is dependent on these three subclasses. Do not idle, first look at the specific implementation.

Filecontentresult

Public ActionResult FileDownload () {    FileStream fs = new FileStream (Server.MapPath ("~/uploads/desert.jpg"), FileMode.Open, FileAccess.Read);    byte[] bytes = new Byte[fs. Length];    Fs. Read (bytes, 0, Convert.ToInt32 (bytes. Length));    Return File (bytes, "Image/jpeg", "desert.jpg");}

Filestreamresult

Public ActionResult FileDownload () {    return File (New FileStream (Server.MapPath ("~/uploads/desert.jpg"), FileMode.Open, FileAccess.Read), "Image/jpeg", "desert.jpg");}

Filepathresult

Public ActionResult FileDownload () {    return File (Server.MapPath ("~/uploads/desert.jpg"), "Image/jpeg", " Desert.jpg ");

Did you see the code above that seems more concise than the file download code in the WebForm in the Codeshark article? Do! Then we can not help but ask: not to say that the file download in MVC relies on Filecontentresult, Filepathresult, Filestreamresult, why there is no exception here is the return file (...) It? This is for you who have been in contact with MVC, believe hard not to pour you, F12 all understand:

(Fig. 1-1)

Original file (...) The example of Filecontentresult, Filestreamresult, Filepathresult is returned behind the method. That's not surprising. So in fact, the above 3-clock implementation of the way you can completely change to the following form:

Filepathresultreturn New Filepathresult (Server.MapPath ("~/uploads/desert.jpg"), "Image/jpeg") {FileDownloadName = "Desert.jpg"};//filestreamresultreturn new Filestreamresult (New FileStream (Server.MapPath ("~/uploads/desert.jpg") , FileMode.Open, FileAccess.Read), "Image/jpeg") {filedownloadname = "desert.jpg"};//filecontentresultreturn New Filecontentresult (System.IO.File.ReadAllBytes (Server.MapPath ("~/uploads/desert.jpg"), "Image/jpeg") { Filedownloadname = "Desert.jpg"};

If you check the source through Ilspay, you will find that the corresponding return File (...) This is true of the internal implementation.

Question 1: What happens if you do not assign a value to Filedownloadnane

Back to look at 1-1, we will also find Filecontentresult, Filestreamresult, Filepathresult download methods, but also each corresponding to the existence of a third parameter Filedownloadnane method overload. So what does this method do for you? Small snippet of code to see:

Public ActionResult FileDownload () {    return File (Server.MapPath ("~/uploads/desert.jpg")}

--------------------------------------------------------------------------------Running Results------------------------------------- ------------------------------------------------------------------------------

By running the results can be seen at a glance, the picture is directly output on the page, this implementation of the image display function. At the same time we can also know that the same is possible:

return new Filepathresult (Server.MapPath ("~/uploads/desert.jpg"), "image/jpeg");

Question 2: What's behind the Filedownloadnane?

Of course, the same is true of the other two ways. Then we can not help but ask: why not give filedownloadname assignment, achieve the effect is completely different? Then you must have thought about what must have been done internally to make a distinction. So take Filepathresult as an example and use Ilspy to see what it is:

(Fig. 1-2)

--------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------

(Fig. 1-3)

Let's look at figure 1-2FileresultClass, there is aFiledownloadnameExposing properties, we know that the ActionResult class will eventually execute the subclass'sExecuteresultmethod, while the fileresult of thein the executeresult method, the Filedownloadname is judged by non-null. If not empty, the response is passed. AddHeader () method to send the file to the client browser. If NULL, the subclass is calledFilepathresultof theoverriding Method WriteFile () (shown in Figure 1-3)output The response stream directly to the page. Of course Filecontentresult, filestreamresult the same reason.

What's the difference between 3:filecontentresult, Filestreamresult, filepathresult file downloads?

Well, to answer this question, needless to say, you have to look at its internal implementation. So let's take a look at what's going on.

Executeresult method of Fileresult , Fileresult Executeresult method Color: #000000; " The subclass of WriteFile method 。 So I just need to look at the WriteFile method you'll know.

Filecontentresult

Filestreamresult

Filepathresult

Take a look at Codeshark's article ASP. NET implementation file download, in this article he summed up the file download 4 ways:

Mode one: TransmitFile implementation download. Writes the specified file directly to the HTTP response output stream without buffering the file in memory.

Way Two: WriteFile implements the download to write the specified file directly to the HTTP response output stream. Note When you use this method on large files, calling this method may cause an exception. The file size that you can use for this method depends on the hardware configuration of the WEB server.

Way three: WriteFile block download

Mode four: Response.BinaryWrite () stream mode download

so compared to the file download in MVC, it's not hard to see, filepathresult actually the Response.TransmitFile party filestreamresult filecontentresult there is no direct control in the article, and it uses the Response.OutputStream.Write way. Another way of Response.BinaryWrite () streaming is not implemented in MVC. Of course on MSDN gives implementation I directly post the implementation code:

Implementation code:

public class binarycontentresult:actionresult{public    Binarycontentresult ()    {    }    //Properties for Encapsulating HTTP headers.    public string ContentType {get; set;}    public string FileName {get; set;}    Public byte[] Content {get; set;}    The code sets the HTTP headers and outputs the file content.    public override void Executeresult (ControllerContext context)    {        context. HttpContext.Response.ClearContent ();        Context. HttpContext.Response.ContentType = ContentType;        Context. HttpContext.Response.AddHeader ("Content-disposition",             "attachment; filename=" + filename);        Context. HttpContext.Response.BinaryWrite (Content);        Context. HttpContext.Response.End ();    }}

Calling code:

Public ActionResult Download (string fn) {    //Check whether the requested file is valid.    String PFN = Server.MapPath ("~/app_data/download/" + fn);    if (! System.IO.File.Exists (PFN))    {        throw new ArgumentException ("Invalid file name or file not exists!");    }    Use Binarycontentresult to encapsulate the file content and return it.    return new Binarycontentresult ()    {        FileName = fn,        ContentType = "Application/octet-stream",        Content = System.IO.File.ReadAllBytes (PFN)    };}

Question 4: So What's the difference between Filecontentresult's Response.OutputStream.Write () and Response.WriteFile ()?

Regarding this question, I looked for a long time, did not get the comparison full wing the answer, here hoped the big God to instruct twos!

File download in Part 2 WebForm

Check out this article for ASP. NET implementation file download at a glance. Four ways not to say more. Here, I have to say that the files in MVC are downloaded by so easy! This is also due to the Microsoft package. So the question comes, in the webform we are not because we should also encapsulate one such implementation, so that in the later use of the time without writing (of course, copy) repeated write this easy to forget the code to write it? Of course, just do it! Online I did not find a package for this implementation (with the great God code can contribute). I simply write one myself, good or bad, I will not say.

1. Defining abstract Classes

Define an abstract column filedownloader, define the public download behavior WriteFile method and the Execute method to execute the download, and the file download name _filedownloadname. The code is as follows:

Public abstract class filedownloader{private string _filedownloadname; Public Filedownloader (String contentType) {if (string.        IsNullOrEmpty (ContentType)) {throw new ArgumentException ("ContentType"); } this.    ContentType = ContentType; public void Execute (HttpContext context) {if (context = = null) {throw new Argumentnulle        Xception ("context"); } HttpResponse response = context.        Response; Response.        ClearContent (); Response. ContentType = this.        ContentType; if (!string. IsNullOrEmpty (this. Filedownloadname)) {context. Response.AddHeader ("Content-disposition", "attachment; Filename= "+ this.        Filedownloadname); } this. WriteFile (context.        Response); Response.        Flush (); Response.    End ();    } protected abstract void WriteFile (HttpResponse response);    public string ContentType {get; private set;} public string FiledownloadnAme {get {return (this._filedownloadname?? string).        Empty);        } set {this._filedownloadname = value; }    }}

2. Create an implementation class

Here to simulate the implementation in MVC to create the corresponding webform in the implementation, in order to easily distinguish the description, I take and MVC in the same class name.

The way to download Filecontentresult in MVC (different from the Filestreamresult partition download) is implemented here:

public class filecontentresult:filedownloader{public    filecontentresult (byte[] filecontents, string contentType)        : Base (contentType)    {        if (filecontents = = null)        {            throw new ArgumentNullException ("filecontents");        }        This. FileContents = filecontents;    }    Public byte[] FileContents {get; private set;}    protected override void WriteFile (HttpResponse response)    {        response. Outputstream.write (this. FileContents, 0, this. filecontents.length);}    }

Filestreamresult (partition Download):

public class filestreamresult:filedownloader{public    filestreamresult (Stream fileStream, String contentType)        : Base (contentType)    {        if (FileStream = = null)        {            throw new ArgumentNullException ("FileStream");        }        This. FileStream = FileStream;    }    Public Stream FileStream {get; private set;}    protected override void WriteFile (HttpResponse response)    {        Stream outputstream = response. OutputStream;        using (this. FileStream)        {            byte[] buffer = new byte[4096];            while (true)            {                int num = this. FileStream.Read (buffer, 0, 4096);                if (num = = 0)                {break                    ;                }                Outputstream.write (buffer, 0, num);}}}    

Filepathresult:

public class filepathresult:filedownloader{Public    filepathresult (string fileName, String contentType)        : Base (ContentType)    {        if (string. IsNullOrEmpty (filename)        {            throw new ArgumentNullException ("filename");        }        This. filename = filename;    }    public string FileName {get; private set;}    protected override void WriteFile (HttpResponse response)    {        response. TransmitFile (this. FileName);}    }

In addition, we also adopted the implementation of Binarycontentresult on Microsoft, here also realize the Binarycontentresult:

public class binarycontentresult:filedownloader{public    binarycontentresult (byte[] filecontents, string ContentType)        : Base (ContentType)    {        if (filecontents = = null)        {            throw new ArgumentNullException (" FileContents ");        }        This. FileContents = filecontents;    }    protected override void WriteFile (HttpResponse response)    {        response. BinaryWrite (filecontents);    }    Public byte[] FileContents {get; private set;}}

In addition to the Httpresponse.writefile (NET 2.0), when using this method on large files, calling this method may throw an exception here, let's call it the old implementation :

public class filepatholdresult:filedownloader{Public    filepatholdresult (string fileName, String contentType)        : Base (contentType)    {        if (string. IsNullOrEmpty (filename)        {            throw new ArgumentNullException ("filename");        }        This. filename = filename;    }    public string FileName {get; private set;}    protected override void WriteFile (HttpResponse response)    {        response. WriteFile (this. FileName);    }

Part 3 Problem Development

In a file download, we may need to get the MIME type of the file automatically, when specifying the file's download type. So how do I get the MIME type of a file? A better answer is given in the MIME type (Content type) of the Mitchell Chu blog. NET get file. Don't repeat it here.

Part 4 The end

Back to the point, because both MVC and WebForm are based on the ASP, so the file download function is implemented with the same component.

Note: Due to limited personal skills, understanding of some concepts may be biased, if you find any bugs in this article, please correct me. Thank you!

Finish.

Mvc&webform Control Study: File download

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.