blog community

Welcome to blog community Sign in | Join | Help
in Search

Wouter van Vugt

This blog is no longer maintained and has moved

Uploading files to ASP.NET using multipart/form-data

Not to hard you might say. ASP.NET supports the use of <INPUT type=”file”> tags on your pages, and the upcoming release also contains a new FileUpload control as a wrapper around this tag. In my opinion there is one mayor shortcoming of this type of solution. It doesn’t easily allow for multiple files to be uploaded at the same time because the number of <INPUT> tags are usually fixed. Searching the internet provides various solutions to this problem. Most of these solutions take the same basic route, either place more <INPUT> tags on your page, or use some clientside javascript magic to upload any number of files.

Well, I am no javascript jockey, I am more at home in the dotNET framework. My solution? Use Windows Forms and ASP.NET’s support for multipart/form-data requests. You can use Windows Forms to provide a much richer UI for the user to interact with. It will also be a lot easier to implement more advanced features such as progress indicators or automatic retries. Now you might say that it isn’t the same. Windows Forms doesn’t run in a browser. And I will say, it does! At least for users of Internet Explorer. This provides the stepping stones required to build a Hotmail like upload solution. You can provide the user with a choice whether she wants to use multiple ASP.NET FileUpload controls which uses <INPUT> tags, use a custom WinForms control hosted in the browser, or use a separately downloadable Windows Forms application.

Before being able to use Windows Forms for uploading files to ASP.NET, a method of sending those files needs to be found. Like I said, ASP.NET supports the use of multipart/form-data requests. This support has been built into the HttpRequest class. When the HttpRequest encounters this type of request, it fills the Files property with the files sent by the client which you can then easily save on the server. Just what the doctor ordered! And because the support is built into the HttpRequest class, you are provided with the choice to use an ASPX webpage or a custom Http handler to handle incoming upload requests. You might even build a solution where both options are used. A Http handler performs the necessary logic for uploading files sent by the Windows Forms application, and an ASPX performs a cross-page postback to this handler. But I haven’t tried this yet.

As you might have guessed I have created a proof-of-concept class which shows it is possible to use dotNET code to upload files to ASP.NET using multipart/form-data. The FileUploadRequest class provides a wrapper around a HttpWebRequest object. Using a single line of code it is possible to upload files.

FileUploadRequest uploadRequest = new FileUploadRequest(

"http://MySite/UploadHandler.aspx",

new NetworkCredential("JoeUser", "pass@word1", "MyDomain"));

uploadRequest.SendFiles("c:\\file1.pdf", "c:\\file2.gif");

uploadRequest = new FileUploadRequest(

"http://MySite/UploadHandler.aspx",

new NetworkCredential("JoeUser", "pass@word1", "MyDomain"));

uploadRequest.SendFiles("c:\\file1.pdf", "c:\\file2.gif");

"http://MySite/UploadHandler.aspx",

new NetworkCredential("JoeUser", "pass@word1", "MyDomain"));

uploadRequest.SendFiles("c:\\file1.pdf", "c:\\file2.gif");

new NetworkCredential("JoeUser", "pass@word1", "MyDomain"));

uploadRequest.SendFiles("c:\\file1.pdf", "c:\\file2.gif");

"c:\\file1.pdf", "c:\\file2.gif");

Now of course there are not only upsides to this. Some problems have been reported where ASP.NET times out when uploading large files. Not everyone browser is able to host Windows Forms controls, rendering this solution useless. But by providing alternatives such as a pure HTML upload page this problem can be overcome. The mayor problem that you will run into when using a browser-embedded Windows Forms control is Code Access Security. Obviously a control can not access the local hard drives by default. The Trusted Zone code group in dotNET also has not got the right permissions assigned by default. This means the user of an embedded control will need to be able to modify these permissions. An application downloaded to the local drive will not suffer from this problem. Running Full Trust allowed me to embed a control in IE which uses the FileUploadRequest class to upload files to ASP.NET. This means all that is required now is finding the exact permissions required. Maybe it is possible to use some kind of certificate mechanism to overcome the CAS problem.

For me personally these problems are all minor, I am planning to use this code to be able to quickly upload small files (images & code) to my homepage, and I am a strong IE user. The FileUploadRequest class is subject to change of course, In the upcoming weeks you can expect a renewed FileUploadRequest class which provides progress indication. I also expect the browser control to be finished by then. More to come... In the mean time you can download this initial version.

Published Saturday, October 08, 2005 2:13 PM by wouterv
Filed under:

Comments

 

Raimond Brookman said:

Another way of solving this is to allow your users to upload a ZIP file, with all the files they want. It also reduces transfer time. Unzipping files is easily done in .NET, either with open source, or commercial libraries such as the one from http://www.xceedsoft.com/
October 8, 2005 8:27 PM
 

Wouter van Vugt said:

This one crossed my mind as well, I am planning to use SharpZipLib for it. Thanks for the tip!
October 10, 2005 1:05 PM
 

Mike Ogden said:

Your class was a great help, however there was one remaining problem that we needed to fix with it. Basically it was eating up the available connections from the server so after a one or two uploads the server would stop responding to that client and consequently the client would hang. This was resolved by cleaning the request and response objects. The article that helped us can be found at: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1047647&SiteID=1 The key is calling the request.abort before closing the request.
March 1, 2007 10:30 PM
Anonymous comments are disabled

This Blog

Syndication

News


Add to Technorati Favorites
Powered by Community Server, by Telligent Systems