Introduction
Uploading and Downloading files is a common part of several applications. There are already plenty of articles written on this subject. In this article I gathered the important concepts that are scattered in different posts and threads in a single place. The POST’ed file(s) are available as parameters directly in actions through model binding. The files in the server can be easily sent as response to the clients through MVC’s rich support of action results
How to upload a file to the Server?
Uploading a file to the server is much simpler than we think. All we need is an html form having encoding type set to multipart/form-data and a file input control. The following are few points to remember.
- Form method =POST
- Input html control with FILE type
- enctype="multipart/form-data”
MVC Form (.cshtml/.aspx)
MVC Form should be like the following. You can write the following code in View.
Point to remember:
An important thing developers forget sometimes is setting the encoding type (enctype) to multipart/form-data. By default the encoding type is application/x-www-form-urlencoded which is insufficient for sending large amount of data to server especially when the form contains files, non-ASCII data and binary data. When you post the form the Content-Type header is set to multipart/form-data. If you forget setting the proper encoding type then only the filename is submitted not the file.
Reading files from POST’ed Request
The POSTed files are available in HttpFileCollectionBase of Request.Files. Following are the code snippets of controller action where you can extract file from the Request. Once you read the POSTed file from the request its really easy to save it to the server.
Upload action
Upload action with Parameter
Instead of manually reading the file from the Request, by taking the advantage of model binding the file can be made directly available as a parameter in the action as shown in the below listing.
Point to remember:
The important thing to note down is the file parameter name should be same as the name of the file input control (in the above case it is photo).
What is HttpPostedFileBase?
MSDN Says, The HttpPostedFileBase class is an abstract class that contains the same members as the HttpPostedFile class. The HttpPostedFileBase class lets you create derived classes that are like the HttpPostedFile class, but that you can customize and that work outside the ASP.NET pipeline. When you perform unit testing, you typically use a derived class to implement members that have customized behavior that fulfills the scenario you are testing.
File binding to the Model?
As many of us already aware, it's the model binding feature that maps the POSTed file to HttpPostedFileBase in the action parameter. The model binding feature relies on two types of components binders and value providers. The value providers are the components that gets the value needed from the particular source (query-strings, form etc.) and feed to binders. The binders are the components that really fills the properties of a model or the parameters in the action with those values
Uploading multiple files
Uploading multiple files is as simple as uploading a single file, all we need is to set the HttpPostedFileBase type as a parameter in the corresponding action method. We can easily achieve this by setting an IEnumerable<HttpPostedFileBase> as action parameter.
How to return/Download a file as response?
How a browser knows what file type is returned from the server?
The Content-Type header is the one that says the browser what kind of file is being returned from the server. For example, to return a pdf file from the server the Content-Type should be set to application/pdf. Likewise to return a png image, the Content-Type should be image/png and so on..
To return a file from server all we have to do is set the proper Content-Type, Content-Disposition headers and write the file into the response. The below code snippet shows how we can return a file just plain from an action without using action results.
Returning files through action results
MVC framework eases the job of returning files through its built-in action results. We don't need to worry about adding any headers in the response the action results will take care.
FileResult
This class mainly does the job of adding Content-Type and Content-Disposition headers into the response. Adding the Content-Type header is not a big deal while determining the value of the Content-Disposition header is not an easy job and the FileResult class uses a private class ContentDispositionUtil for that purpose
There are three built-in classes that implements FileResult: FilePathResult, FileContentResult and FileStreamResult.
FilePathResult
FileContentResult
The FileContentResult writes the complete byte array to the response's OutputStream at-once. You can see the complete code of FileContentResult
FileStreamResult
The FileStreamResult reads chunks of data from the stream and write into the response. The size of each chunk is 4KB and this can't be changed through code or config.
References
Read more articles on MVC: