asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Browser-based File Uploading Under the Microscope
By Peter Persits
Rating: not yet rated
Rate this article


  • email this article to a colleague
  • suggest an article

    Introduction

    Browser-based file uploading is a great way to transfer arbitrary files from a client machine to the Web server. The only software that the user needs is an RFC1867-enabled browser such as Netscape 3.0+, IE 4.0+, or IE 3.0 with an upload add-on. Uploading is performed via an HTML form with the attribute ENCTYPE="multipart/form-data". This form must also contain one or more <INPUT TYPE=FILE> items with which the user specifies local files to be uploaded.

    The ENCTYPE="multipart/form-data" attribute instructs the browser to send the form data to the server in a multi-part format where each item on the form is accompanied by a number of MIME headers and separated from the rest of the items by delimiters. This MIME data must be parsed by a server-side process to extract individual items. Although theoretically achievable with pure ASP script, this task should really be delegated to a high-performance compiled component such as AspUpload from Persits Software, Inc. (http://www.persits.com).

    Using the Request.BinaryRead Method to Examine POST Data

    Let's start our exploration of file uploading by examining a posting sent by a regular HTML POST form without an ENCTYPE attribute. We will do so with the help of the Request.BinaryRead method. This method gives us access to the raw (unparsed) data sent to the server by a

    form. This method takes one parameter which specifies the number of bytes to read. We want to read the entire block of data sent, so will simply pass a value returned by another method of the Request object, TotalBytes.

    The Request.BinaryRead method is a rare guest in ASP scripts, simply because Request.Form and Request.QueryString are much more convenient to use. Besides, this method packs the result data in a Variant-wrapped safe array of bytes, which is a tough nut to crack for a scripting language designed to work only with Variants and safe arrays of Variants. But when it comes to file uploading, BinaryRead becomes absolutely invaluable.

    The following HTML form is quite trivial and does not have an ENCTYPE attribute:

    
    <HTML>
    <FORM METHOD=POST ACTION=Script.asp>
    <INPUT TYPE=TEXT NAME=Item1>
    <INPUT TYPE=HIDDEN NAME=Item2 VALUE=Value2>
    <INPUT TYPE=SUBMIT>
    </FORM>
    </HTML>
    
    
    This form invokes the following simple script:
    
    <HTML>
    <BODY>
    <%
    n = Request.TotalBytes
    data = Request.BinaryRead(n)
    For i = 1 to n
    Response.Write MidB( data, i, 1 )
    Next
    %>
    </BODY>
    </HTML>
    
    
    Note
    We use the MidB function to access individual bytes of the data array returned by BinaryRead.

    Once the form is submitted, the script will produce something like this:

    
    Item1=test+test&Item2=Value2
    
    
    You certainly recognize the standard URL encoding.

    Now let's add the ENCTYPE="multipart/form-data" attribute to our <FORM> tag and submit it again.

    The output will look quite differently now:

    
    -----------------------------7ce9c39120306
    Content-Disposition: form-data; name="Item1"
    
    test test
    -----------------------------7ce9c39120306
    Content-Disposition: form-data; name="Item2"
    
    Value2
    -----------------------------7ce9c39120306--
    
    
    There are two sections separated by a delimiter in this data block, each corresponding to an item on our form. Each section begins with the MIME header Content-Disposition.

    If we attempt to access individual form items using the standard Request.Form collection, we will get absolutely nothing. The Form collection is now totally useless since it can only work with data in the standard URL encoding format.

    We will conclude our little research by adding an <INPUT TYPE=FILE NAME=FileItem> item to our form. This item shows up in the browser as an input box with a "Browse" button sitting next to it.

    Note
    If your browser does not show the "Browse" button it most probably means that the browser does not support file uploading.
    Clicking the Browse button invokes a "Choose File" dialog which lets us pick a file for uploading. For this example, I picked a small GIF file and here is the output that I got:
    
    
    -----------------------------7ce25134120306
    Content-Disposition: form-data; name="FileItem"; filename="D:\HomePage\New\bg.gif"
    Content-Type: image/gif
    
    GIF89aà  ¢ÿÿÿÿààà}}}^^^¦Ô,à   
    -----------------------------7ce25134120306
    Content-Disposition: form-data; name="Item1"
    
    
    -----------------------------7ce25134120306
    Content-Disposition: form-data; name="Item2"
    
    Value2
    -----------------------------7ce25134120306--
    
    
    You can see that the binary file bg.gif turns out to be embedded in the first section of the multi-part data block. Unlike Base64 email attachments, the file is not encoded in any way.

    Notice that the Content-Disposition header for the file section has one more attribute, filename, which is set to the original full path of the file being transported. Also, the file section has one more MIME header, Content-Type.

    Uploading Files with AspUpload

    You could, of course, write some ASP script that would parse the data array returned by Request.BinaryRead, extract individual file, and save them on hard drive. Fortunately, there are several inexpensive uploading components out there that will save you the trouble.

    AspUpload from Persits Software (http://www.persits.com) will do the job in just two lines of ASP code. This component handles multiple uploaded files as well as non-file items.

    For our first example we will use the following HTML form that allows us to upload up to three files simultaneously:

    
    <HTML> 
    <BODY BGCOLOR="#FFFFFF"> 
    <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript1.asp"> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE1"><BR> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE2"><BR> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE3"><BR> 
    <INPUT TYPE=SUBMIT VALUE="Upload!">
    </FORM>
    </BODY> 
    </HTML>
    
    
    The upload script UploadScript1.asp looks like this:
    
    <HTML> 
    <BODY> 
    <% 
    Set Upload = Server.CreateObject("Persits.Upload.1") 
    Count = Upload.Save("c:\upload")
    %> 
    <% = Count %> files uploaded. 
    </BODY> 
    </HTML>
    
    
    The first line of the script simply creates an instance of the AspUpload component. The second line calls the Save method and passes the destination directory as a parameter. The Save method internally calls Request.BinaryRead, parses the data array returned, extracts the files contained in the posting, and saves them in the specified destination directory under their original names. This method returns the number of successfully uploaded files.

    You may use any or all input boxes on the form. AspUpload is smart enough to figure out which boxes are being used and which are not.

    Accessing Individual Files and Non-File Form Items

    Our next form will contain both file and regular text items:

    
    <HTML> 
    <BODY BGCOLOR="#FFFFFF"> 
    <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript2.asp"> 
    File 1:</TD><TD><INPUT TYPE=FILE NAME="FILE1"> 
    Description 1:<INPUT TYPE=TEXT NAME="DESCR1"><BR> 
    
    File 2:<INPUT TYPE=FILE NAME="FILE2"> 
    Description 2:<INPUT TYPE=TEXT NAME="DESCR2"><BR> 
    <INPUT TYPE=SUBMIT VALUE="Upload!">
    </FORM>
    </BODY> 
    </HTML>
    
    
    Here is the corresponding upload script UploadScript2.asp:
    
    <HTML> 
    <BODY> 
    <% 
    Set Upload = Server.CreateObject("Persits.Upload.1") 
    Upload.Save "c:\upload"
    %> 
    Files:<BR> 
    <% 
    For Each File in Upload.Files 
    Response.Write File.Name & "=" & File.Path & " (" & File.Size & ")<BR>"
    Next
    %> 
    <P> 
    Other items:<BR> 
    <% 
    For Each Item in Upload.Form 
    Response.Write Item.Name & "=" & Item.Value & "<BR>"
    Next
    %> 
    </BODY> 
    </HTML>
    
    
    As I mentioned before, we can no longer use the Request.Form collection to access individual items on a form with the ENCTYPE attribute. But not to worry: AspUpload provides a Form collection of its own, which is similar to Request.Form. We can access individual items in this collection using integer indexes or string names, e.g.
    
    Response.Write Upload.Form(1)
    
    
    or
    
    Response.Write Upload.Form("DESCR1")
    
    
    We can also scroll through the items in the collection using the For-Each statement as shown in the script above.

    The Upload.Form collection only contains non-file form items, i.e. items other than <INPUT TYPE=FILE>. AspUpload provides one more collection, Upload.Files, to represent the files coming from <INPUT TYPE=FILE> items of the form. Each item in this collection is an object of the type UploadedFile. This object provides a lot of methods and properties which enable you to query and manipulate each uploaded file.

    Example 2 will produce something like this:

    
    Files: 
    FILE1=c:\upload\File1.xls (108544) 
    FILE2=c:\upload\File2.zip (211687) 
    
    Other items: 
    DESCR1=bla bla 
    DESCR2=test test 
    
    
    Notice that we have obtained the files' destination paths and sizes via the Path and Size properties of the UploadedFile object, respectively.

    It is important to remember that you cannot use the Upload.Form or Upload.Files collections until the Save method is called. For example, if you want to enable your users to specify the destination directory in the upload form, you may be tempted to write the following code:

    
    ' Incorrect
    n = Upload.Save(Upload.Form("Path"))
    
    
    This will not work because the Form collection will not be populated until the Save method is called. The correct way of doing this would be to upload files to a fixed directory and then move or copy them to the user-specified directory:
    
    ' Correct
    n = Upload.Save "c:\upload"
    For Each File in Upload.Files
    	File.Copy Upload.Form("Path") & "\" & File.ExtractFileName
    Next
    
    

    Saving Uploaded Files in Database as Blobs

    Many database management systems like MS Access or SQL Server can store arbitrary files as "binary large objects" (BLOBs). An MS Access table can store binary files in data fields of the type OLE Object. In SQL Server, the corresponding data type is called BINARY. The stored files can later be retrieved for downloading or displaying using ADO.

    AspUpload allows you to store an uploaded file in a database table in just one line of ASP code.

    The HTML file for example 3 is almost identical to that of example 1 (except for the ACTION attribute):

    
    <HTML> 
    <BODY BGCOLOR="#FFFFFF"> 
    <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="UploadScript3.asp"> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE1"><BR> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE2"><BR> 
    <INPUT TYPE=FILE SIZE=60 NAME="FILE3"><BR> 
    <INPUT TYPE=SUBMIT VALUE="Upload!">
    </FORM>
    </BODY> 
    </HTML>
    
    
    Here is the script UploadScript3.asp:
    
    <HTML> 
    <BODY> 
    <% 
    Set Upload = Server.CreateObject("Persits.Upload.1") 
    Upload.Save "c:\upload" 
    On Error Resume Next 
    For Each File in Upload.Files 
    File.ToDatabase "DSN=data;UID=sa;PWD=xxx;",_
    	"insert into Blobs(id, Path, BigBlob)" &_
    	"values(12, '" & File.Path & "', ?)"
    if Err <> 0 Then 
    Response.Write "Error saving the file: " & Err.Description
    Else 
    File.Delete 
    Response.Write "Success!"
    End If
    Next
    %> 
    </BODY> 
    </HTML>
    
    
    The workhorse method in this example is File.ToDatabase which accepts two arguments. The first argument is an ODBC connection string in the format
    
    "DSN=<datasource name>;UID=<userid>;PWD=<password>;<other optional attributes>"
    
    
    The second argument is an SQL INSERT or UPDATE statement which must contain a question mark (?) representing the actual file being saved in the database. In the example above we insert three values in the table Blobs: 12 in the field "id", the file path in the field "Path", and the actual uploaded file in the field "BigBlob".

    Notice that this example uses the On Error Resume Next statement to catch exceptions that may be thrown by AspUpload's methods in case of an error.

    It is not uncommon to store GIF and JPEG images in a database table. To retrieve an image from the table and display it on an HTML page, you don't need to use any third-party component. ADO will do the job for you.

    Put a regular <IMG> tag on your HTML page with the SRC attribute pointing to an ASP script, e.g.

    
    <IMG SRC="GetImage.asp?id=4">
    
    
    The GetImage.asp script may look like this:
    
    <%
    Set db = Server.CreateObject("ADODB.Connection")
    db.Open "data"
    Set rs =db.Execute("SELECT BigBlob FROM Blobs where id = " & Request("id") )
    Response.ContentType = "image/jpeg" '(or "image/gif")
    Response.BinaryWrite rs("BigBlob")
    %>
    
    

    More Info on AspUpload

    AspUpload provides tons of features not covered in this article that you may find very useful, such as unique filename generation to avoid collisions with existing files in the upload directory. Or you can configure the component to truncate or reject files that exceed certain size. And finally you can find features no other uploading component on the market offers, such as NT Access Control List (ACL) manipulation or remote ActiveX DLL registration.

    For more information and to download your free trial copy of AspUpload, visit the Persits Software web site at http://www.persits.com/aspupload.html. You will also find a live demo application that allows you to actually upload files to our server. If you have questions don't hesitate to write to us at info@persits.com.

    About the Author

    Peter Persits is the founder and president of Persits Software, Inc., the vendor of the popular ASP components AspUpload, AspNTUser, AspGrid, AspAccessControl, and AspEmail. He has been developing software for Microsoft platforms for over ten years. Peter holds a Master's degree in Computer Science from American University (Washington, DC), and is a Microsoft Certified Solution Developer. Peter Persits currently lives in Arlington, VA.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Supporting Products/Tools
    AspUpload
    AspUpload is an Active Server component which enables an ASP application to accept, save and manipulate files uploaded with a browser. The files are uploaded via an HTML POST form using RFC 1867. AspUpload can then manipulate the uploaded files in a number of ways which include ACL manipulation, attribute changes, saving to a database, and ActiveX DLL registration.
    [Top]
    ABCUpload
    Uploading files is as simple as ABC with ABCUpload. Our Pure HTML Progress Bar allows your visitors to see the progress of their upload in real time with absolutely no client side software. We also offer a number of other advanced technical features including Unicode Compliant, 120% MacBinary Compatible, BLOB Aware, support for foreign language uploads.

    ABCUpload also supports COM+ and is also available in a .NET version.

    [Top]
    ActiveFile

    With ActiveFile's advanced features, such as restart of interrupted downloads, download failure detection, and industry standard data compression, it's no wonder that companies like Associated Press and Xerox are Infomentum OEM partners. ActiveFile is the professional’s choice for leading edge capabilities that can’t be found in any other file component.

    If you are looking for an intelligent way to exchange files between your ASP or ASP.NET application and web clients, the search is over. Compliant with RFC 1867, ActiveFile provides both file upload and download capabilities that work seamlessly with all of the leading web browsers. Using Active Server Pages or ASP.NET scripting, your application can manipulate files and directories using a robust set of objects and methods provided by the ActiveFile component.

    [Top]
    aspSmartUpload
    aspSmartUpload is a FREE ASP component wich provides you with all the upload/download features you need to transfer files to a server using a browser.
    [Top]
    CyberShop
    An all-in-one shopping cart system that provides a universal hook to all shopping pages on your Web site, regardless what you sell. Runs for all IIS based Web servers under Windows 95, 98, NT 4.0, NT 2000. Works with all versions of FrontPage.
    [Top]
    Posting Acceptor
    Microsoft Posting Acceptor allows Microsoft Internet Information Server (IIS) to accept Web content posts (files) from Microsoft Web Publishing Wizard or other clients using the RFC1867 multi-form/posting method through an http connection. Microsoft Posting Acceptor can also accept content posts from Internet Explorer 3.0 (with the ActiveX Upload control provided with Microsoft Posting Acceptor) and Netscape Navigator 2.02 or greater through forms.
    [Top]
    Power-Web AspUpload
    Enables ASP to manipulate MIME type data (Uploaded file) transmitted from client's PC as Request Objetcs.
    [Top]
    SA-FileUp
    FileUp is the standard in transactional file uploads and secure downloads. Allows dynamic applications to accept, save, and manipulate files uploaded via a browser. Files can be of any format such as Word documents, images, or plain text. FileUp is the most comprehensive transactional file transfer controls: supports foreign character sets; guarantees synchronization between upload processing and database transactions; full COM+ integration; simplified error handling; guaranteed integrity when uploading multiple files; server-side progress indicator; performance monitor counters; MacBinary decoding, recursive directory uploads and more! Besides the most complete feature set, FileUp includes documentation, a large set of sample ASP pages, and an extensive tutorial. .NET, ASP & VB
    [Top]
    ScriptUtils
    Allows working with safearray binary data. Enables binary file upload to the ASP and download from ASP with on-fly compression or generation binary data (Using Response.BinaryWrite and Request.BinaryRead). Enables calling some of Kernel and Advapi functions and work with processes and threads.
    [Top]
    Other Articles
    May 22, 2001 - Using XML to Improve File-Upload Processing
    In this article, Marco Nanni examines an example of multiple binary file uploading for Web applications using XML, without the typical limitations of traditional file upload processing.
    [Read This Article]  [Top]
    May 4, 2001 - Creating a File-Upload User Control with ASP.NET
    Build multipart MIME upload forms using the InputFile HTML Server Control and learn how to take advantage of the file-upload services built into the HTTP runtime for ASP.NET. Save the uploaded file to disk without granting anonymous users file-write access to folders on your Web server. Then wrap all this in a new ASP.NET user control, which will allow you to add file upload capabilities to almost any Web page quickly and easily.
    [Read This Article]  [Top]
    Mar 14, 2001 - Advanced File Uploading
    To design an industrial-quality solution, one must delve into both how basic uploads work and the more advanced issues of file uploading.
    [Read This Article]  [Top]
    Oct 3, 2000 - Understanding File Upload
    Building an upload file mechanism on a Web server can often require using a costly DLL. Tiago Halm's article shows you how to upload a file using only Active Server Page (ASP) code and Internet Explorer. Sample code is provided.
    [Read This Article]  [Top]
    Jul 23, 1999 - Uploading Multiple Files
    This article by Sander Duivestein examines the upload components currently on the market and gives his opinion about how they work. Sander takes the reader through his requirements for uploading and the solutions that he used.
    [Read This Article]  [Top]
    Mar 11, 1999 - Down and Dirty Browser Uploading with a VB ASP Component
    This article was written for VB5/VB6 or ASP programmers want to explore server-side ActiveX ASP components and may be looking for a “how to” code demonstration of uploading files from an Internet browser.
    [Read This Article]  [Top]
    Nov 20, 1998 - An Insider View of Uploading Files using ASP
    In this article David Wihl, of Software Artisans, discusses the options available for uploading files to a web server. He also compares SA-FileUp with the Posting Acceptor and provides example code for uploading files with SA-FileUp.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info

    Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers