Practical ASP.NET

Getting Files To and From the Server

The FileUpload control and the ASP.NET Response object let you move files between the browser and the server. And moving in each direction just requires a few lines of code.

On occasion, what the user enters into the controls on the page isn't enough -- sometimes the user needs to give you a complete file. The reverse is also true: Sometimes sending the user a page isn't enough: you need to get a whole file down to the user's computer.

Moving Files to the Service
To get a file to the server you need to add an input tag of type file to your page. In ASP.NET 2.0 the FileUpload server-side control does just that:

‹input type="file" name="FileUpload1" id=" FileUpload1" /›

When the user uses the FileUpload control in the browser, the browser opens up a file dialog that lets the user select the file to upload. The file is not, however, uploaded until the user submits the page. At that point, on IIS, the file is uploaded to a quarantine area.

Back on the server, the FileUpload control doesn't fire an event on the server when it's used in the browser -- it has no equivalent to a Button's Click event. Instead, to determine if the user used the control to upload a file, you have to check the control's HasFile property, as this example does:

If Me.FileUpload1.HasFile Then
End If

If a file was uploaded, you'll want to move the file out of the quarantine area. You can use either the control's SaveAs method (which allows you to save the file to physical path on the hard disk) or read the file byte by byte through the control's FileContent property (which is a stream). You can retrieve the name that the file had on the user's disk from the control's FileName property.

This example converts the filename to a physical path in the website using the Server object's MapPath method and the FileName property:

If Me.FileUpload1.HasFile Then
Me.FileUpload1.SaveAs( _
Server.MapPath( System.IO.Path.GetFileName(
Me.FileUpload1.FileName)))
End If

Of course, you want to protect yourself from saving malicious files to your server. You can use the ContentType on the control's PostedFile property to check the MIME type of the file. This code checks that the file being uploaded is a text file:

If Me.FileUpload1.HasFile AndAlso _
Me.FileUpload1.PostedFile.ContentType = "text/plain" Then

Finally, you want to protect yourself from denial of service attacks. These attacks can take two forms: uploading really, really large files or uploading standard sized files really, really slowly. You can cut off both attacks by specifying a maximum file size and upload time in your web.config file with the httpRuntime element.

This example limits files to 1024 kilobytes (one megabyte) in size and uploads to five minutes (300 seconds) in duration:

   ‹httpruntime maxrequestlength="1024" executiontimeout="300"›‹/httpruntime›

Getting Files to the Client
I suspect that there are probably several ways that you can send files to the client. However, I've been using a mechanism based around the Response object since I started programming way back in ASP.

Fundamentally, instead of returning HTML text to the client, I send some other form of data. As part of sending the data to the client, I tell the browser what kind of data I'm sending and force the browser to open a File Download dialog box.

I first convert the data into a byte array. This example assumes the output is in a string called Exportdata:

Dim abytOutput() As Byte
abytOutput = (New System.Text.UTF8Encoding).GetBytes(ExportData)

Now that I have a byte array, I use the Response object for the page to set the ContentType of what I'm sending to the client. In this example, I set the ContentType to "text/csv" after clearing the buffer:

Response.ClearContent()
Response.ContentType = "text/csv"

My next step is to add a Content-Disposition header to my output. This will cause the browser to display the File Download dialog with a default file name. This example sets the file's default name to "MyFile.csv" after clearing any existing headers:

Response.ClearHeaders()
Response.AddHeader("Content-Disposition",
"attachment;filename=MyFile.csv;")

Finally, I write the byte array to the client using the Response object's OutputStream property. The Write method accepts the byte array, a start point and an end point. Typically, I start in position zero and write all the bytes in the array as in the following example. After sending the content to the client, I flush the output buffer and close the stream:

Response.OutputStream.Write(abytOutput, 0, abytOutput.Length)
Response.Flush()
Response.Close()

With the FileUpload control and the Response object, you can move files in both directions: up to the server and down to the client.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events