Uploading Files with ASP

cUpload: A closer look

Lets take a closer look at this cUpload class first. After a few public variables for the class, you'll notice the

Public Sub OnStartPage(PassedScriptingContext As ScriptingContext)

line, which doesn't appear to be called by anything. In fact, this procedure is called by the Active Server Pages engine when the object is initialized in our ASP script, and passes us a ScriptingContext object. This object contains all the objects available to your ASP script; Response, Request, Server etc. In this instance, we are only interested in the Request object (what has been sent to the ASP script), so we save it to our MyRequest object using

Set MyRequest = PassedScriptingContext.Request

We then proceed to call the BuildForm procedure, which parses the data sent to us via the form on upload.asp. This is where the bulk of our code lies.

As the form was posted using the encoding method, we cannot access the posted objects using the standard Request.Form object. Instead, we read the entire HTTP header into a variable. First, we get the length of the header:

varByteCount = MyRequest.TotalBytes

and then we read the header into varHTTPHeader using

varHTTPHeader = StrConv(MyRequest.BinaryRead(varByteCount), vbUnicode)

You will notice that we have also converted the header into Unicode. This is to make it easier for us to parse the posted data; instead of receiving binary data, we receive at least some readable characters. Below is a sample of what might now be present in varHTTPHeader.

-----------------------------7d130d3810678
Content-Disposition: form-data; name="thefile"; filename="C:\devpad_description.txt"
Content-Type: text/plain

Developers Pad - the ultimate programming editor. Fully configurable, with syntax highlighting, auto-indent, code library, powerful project view, quick-tag, find & replace, find in files, add-ins and more!
-----------------------------7d130d3810678
Content-Disposition: form-data; name="filedescription"


-----------------------------7d130d3810678
Content-Disposition: form-data; name="folder"

0
-----------------------------7d130d3810678--

As you can see, each field is seperated by -----------------------------7d130d3810678. Next, we are told the we are type of content, and the field name. In the case of the file, we are also given the filename and content type. Finally, we are given the value of that field. The BuildForm procedure now parses this data, and creates the correct number of form objects. As the delimiter may vary, we check it by taking the first 76 bytes:

varDelimeter = LeftB(varHTTPHeader, 76)

Next, we find where the first field is by searching for ; name="

lngFormFieldNameStart = InStrB(lngFormFieldNameStart + 1, varHTTPHeader, "; name=" & Chr(34))

Note we use the InStrB function so that we are returned the byte position rather than character position. Now, we start a Do...Loop which continues until lngFormFieldNameStart = 0. For each field, we first initialize the FormField object:

Set clsFormField = New cFormItem

Next, we find out where the name property is going to end. We do this by searching for a " character (Chr(34)), from the fields starting position, plus the length of ; name=". Now that we have the start and end positions, we can retreive the name of the field:

lngFormFieldNameEnd = InStrB(lngFormFieldNameStart + Len(StrConv("; name=" _
     & Chr(34), vbUnicode)), varHTTPHeader, Chr(34)) + Len(StrConv(Chr(34), vbUnicode))

strFormFieldName = MidB(varHTTPHeader, lngFormFieldNameStart + _
     Len(StrConv("; name=" & Chr(34), vbUnicode)), (lngFormFieldNameEnd - _
     Len(StrConv(Chr(34), vbUnicode))) - (lngFormFieldNameStart + _
     Len(StrConv("; name=" & Chr(34), vbUnicode))))

Now we check to see if there is a ; after the name field... If there is, we know it is a file, otherwise, it isn't.

If it is a file, we proceed to get the filename: and ContentType properties. After the ContentType property, we search for two vbCrLf (new lines), after which is the file data. We now save all this extra file data (filename, file size, content type etc) to the clsFormField object.

'add form field data
clsFormField.Add "FileName", strFileName
clsFormField.Add "FileLen", lngFileLength
clsFormField.Add "ContentType", strContentType

'save the files data to the collection...
clsFormField.FileData = MidB(varHTTPHeader, lngFileDataStart, lngFileLength)

If the form field isn't a file, we perform a similar operation, except we skip searching for the filename, and just get the form fields value instead. Finally, we save the fields name, and add the clsFormField object to our varFields collection:

clsFormField.Add "Name", strFormFieldName
'Assign formfieldnames and formfieldvalues to collection
varFields.Add clsFormField, strFormFieldName

We then reset the clsFormField, and search for another field to process.... and this continues until we have parsed all the fields. We then return the varFields collection for use by our ASP script.

You might also like...

Comments

About the author

James Crowley

James Crowley United Kingdom

James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audien...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“In theory, theory and practice are the same. In practice, they're not.”