Upload images in classic ASP

Uploading images via Web pages is a common task with inherent support in HTML. But the process gets complicated when multiple images are uploaded and must be processed separately. Here's one solution that uses classic ASP.

Recently, I worked on a project that focused on moving a warranty claim system to the Web. A major portion of the project involved storing images related to the claims. These items were involved in the process:
  • ·        A database table to store the images
  • ·        An ASP page to upload the images
  • ·        A script to interpret the uploaded images and store them in the table
  • ·        A page for viewing the images' names pertaining to a selected claim number
  • ·        A page to display the actual image

Let's take a closer look at each aspect of the application.

The table
This was just a quick-and-dirty demo to test the viability of the concept, so we used Microsoft Access instead of a more robust database like SQL Server, Oracle, or MySQL. Since there is more to warranty claims and images than just the claim numbers and the images themselves, the table consists of more than two columns, as shown in Figure A. The columns are self-explanatory, with the exception of the image content type, which I'll describe later, and the data type of the picture. OLE Object is used as a replacement for a binary large object (BLOB) because we're using Access.

Figure A

The upload page
When I first received this assignment, I spent about 10 minutes wondering how to upload a file from the client to the ASP server. Remembering that the HTML input element has a type attribute that can be set to file helped cure my attack of process overengineering, as did remembering the accept attribute. This attribute facilitates the filtering of listed files by MIME types. Unfortunately, the implementation is somewhat spotty.

The form element is the final client-side part of the upload page. The only unusual aspect of this element related to file uploads is that the method attribute is set to post, and the enctype attribute is set to multipart/form-data, which is the standard for sending multiple files in one bundle. Finally, to keep text and files separate when the form is submitted using client-side JavaScript, I added the claim number to the form's action attribute. Figure B shows a screen shot of the final page, and the code appears in Listing A.

Figure B

The server-side script
Once the form has been submitted and the script that's specified in the form's action attribute has control, the script determines what to do next. This is no small endeavor, because the claim number, all of the files, and their attributes are in the same convenient bundle that was sent from the client. It's possible to separate this data programmatically, but I chose to use aspSmart's free aspSmartUpload component to split the files from each other. This component, which includes documentation and examples, simplified what could have been a nightmare.

The aspSmartUpload component's Files object provides a method to access individual files in a collection. The properties of each file are retrieved using the File object, including the filename, MIME type, MIME subtype, and the file itself.

The image list and display
Listing the images by both claim number and filename makes more sense than just displaying the images. This allows dial-up users to choose an image without tying up bandwidth. With this idea in mind, I created the page shown in Figure C. You'll find the companion code in Listing B.

Figure C

Usually, when an image is displayed on a page, the image is coming from a file. For example, the content type is known from the file extension, such as whatever.jpeg or stuff.gif. Unfortunately, the image is stored in a table, so we don't have this luxury—but we do know the content type.

Using the content type in a script invoked in a pop-up, an IFrame, or a Frame can set the response object's content type and write the image as binary in the following manner:
Response.ContentType = rsImage("content_type")
Response.BinaryWrite rsImage("picture")

The specific details of this are in Listing C.

Don't let the implementation details stop you
This project started as one of those things that everyone knew could be done, but the implementation details slowed things down. Each separate hurdle was a logical progression leading to the next.




Editor's Picks