Upload File example.

Its been a while since i wrote something , so i thought i better step up my game and get posting again. Every so often i am asked if I had ever written a script to upload a physical file onto the data  collection server. So this article will show you how this can be done, the main thing to think about is you must be able to copy some files to the server and make a few directories. If you are running this in a cluster you will have to think a little differently , but here is some code that can be used.
First off , let’s get some metadata,

Metadata(en-AU, Question, Label)
UploadFrame "{Frame}"
info;
End Metadata

Now we need some routing,

Routing(Web)

Dim sForm,sAction,sNewName,sNewPath,sLogin,sName

sLogin = "myname"
sName = sLogin + "_" +  MakeCleanName(ctext(now()))

sAction = "C:\Inetpub\wwwroot\UploadFiles\" + sName + ".asp"
sNewName = sName + ".pdf"
sNewPath = "c:\temp\test\"

From this code I hope you can see that we have declared a few variables. What is going to happen is that we are going to create an ASP on the fly , so we need to give it a random name, this file is then going to sit on the server in a folder called “UploadFile” when the file is run , it will prompt the user for the file and upload it to a folder on the C drive of the machine. “c:\temp\test\”

Now some more routing code,

MakeUploaderASP(sAction,sNewName,sNewPath)

sForm = "C:\Inetpub\wwwroot\UploadFiles\" + sName + ".htm"
MakeUploadForm(sForm,sName + ".asp")
UploadFrame.Label.Inserts["Frame"] = ""
UploadFrame.Ask()

The next bit of code calls a function that creates the ASP file and it also makes an htm file that is used in the iframe. Finally we have a label insert that inserts the iframe code  into the UploadFrame question which is then presented to the user.
We have a few functions in this code the first is as follows

Function MakeCleanName(sName)
sName = replace(sName,":","")
sName = replace(sName,"/","")
sName = replace(sName," ","")

MakeCleanName = sName
End Function

 
The MakeCleanName function takes a string and turns it into a usable filename.  Next we have the make upload form,

Sub MakeUploadForm(sFileName,sAction)

Dim oFSO, oFile

 Set oFSO = CreateObject("Scripting.FileSystemObject")
 
 Set oFile = oFSO.CreateTextFile(sFileName, True)

  oFile.WriteLine("")
  oFile.WriteLine("")
  oFile.WriteLine("")
  oFile.WriteLine("")
  oFile.WriteLine("")
  oFile.WriteLine("
")   oFile.WriteLine(" ")   oFile.WriteLine(" ")   oFile.WriteLine(" ")   oFile.WriteLine(" 
Select a file to upload:
")   oFile.WriteLine("
")   oFile.WriteLine("")   oFile.WriteLine("")  oFile.Close()  Set oFSO = Null    End Sub

This code creates the html file , using the file system object , that is presented to the user. The action of the form , the thing that does the upload , is generated in this next function.

Sub MakeUploaderASP(sFileName,sNewName,sNewPath)

Dim oFSO, oFile

 Set oFSO = CreateObject("Scripting.FileSystemObject")
 
 Set oFile = oFSO.CreateTextFile(sFileName, True)

  oFile.WriteLine("<%@ Language=VBScript %>")
  oFile.WriteLine("<%Option Explicit%>")
  oFile.WriteLine("")
  oFile.WriteLine("<%")
  oFile.WriteLine("Dim Uploader, File")
  oFile.WriteLine("Set Uploader = New FileUploader")
  oFile.WriteLine("")
  oFile.WriteLine("Uploader.Upload()")
  oFile.WriteLine("")
  oFile.WriteLine("If Uploader.Files.Count = 0 Then")
  oFile.WriteLine(" Response.Write ""File(s) not uploaded.""")
  oFile.WriteLine("Else")
  oFile.WriteLine(" ' Loop through the uploaded files")
  oFile.WriteLine(" For Each File In Uploader.Files.Items")
  oFile.WriteLine("  ")
  oFile.WriteLine("  File.FileName = """ + sNewName + """")
  oFile.WriteLine("  File.SaveToDisk """ + sNewPath + """")
  oFile.WriteLine("")
  oFile.WriteLine("  Response.Write ""File Uploaded: "" & File.FileName & ""
""")   oFile.WriteLine("  Response.Write ""Size: "" & File.FileSize & "" bytes
""")   oFile.WriteLine("  Response.Write ""Type: "" & File.ContentType & ""

""")   oFile.WriteLine(" Next")   oFile.WriteLine("End If")   oFile.WriteLine("")   oFile.WriteLine("%>")    oFile.Close()  Set oFSO = Null   End Sub End Routing

This function also uses the file system object to create a asp file on the fly. You will also notice that it references an upload.asp file.  The content of which is as follows , and not created by me.



<%

'***************************************

' File:          Upload.asp

' Author:        Jacob "Beezle" Gilley

' Email:         avis7@airmail.net

' Date:          12/07/2000
' Updated:       12/20/2002
' Modified by:   Will Bickford
' Email:         wbic16@hotmail.com

' Comments: The code for the Upload, CByteString,

'    CWideString subroutines was originally

'    written by Philippe Collignon...or so

'    he claims. This script is provided
'    "AS-IS" without support of any kind.

'****************************************



Class FileUploader

 Public  Files

 Private mcolFormElem



 Private Sub Class_Initialize()

  Set Files = Server.CreateObject("Scripting.Dictionary")

  Set mcolFormElem = Server.CreateObject("Scripting.Dictionary")

 End Sub



 Private Sub Class_Terminate()

  If IsObject(Files) Then

   Files.RemoveAll()

   Set Files = Nothing

  End If

  If IsObject(mcolFormElem) Then

   mcolFormElem.RemoveAll()

   Set mcolFormElem = Nothing

  End If

 End Sub



 Public Property Get Form(sIndex)

  Form = ""

  If mcolFormElem.Exists(LCase(sIndex)) Then Form = mcolFormElem.Item(LCase(sIndex))

 End Property



 Public Default Sub Upload()

  Dim biData, sInputName

  Dim nPosBegin, nPosEnd, nPos, vDataBounds, nDataBoundPos

  Dim nPosFile, nPosBound



  biData = Request.BinaryRead(Request.TotalBytes)

  nPosBegin = 1

  nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))

  If (nPosEnd-nPosBegin) <= 0 Then Exit Sub

  vDataBounds = MidB(biData, nPosBegin, nPosEnd-nPosBegin)

  nDataBoundPos = InstrB(1, biData, vDataBounds)

  Do Until nDataBoundPos = InstrB(biData, vDataBounds & CByteString("--"))

   nPos = InstrB(nDataBoundPos, biData, CByteString("Content-Disposition"))

   nPos = InstrB(nPos, biData, CByteString("name="))

   nPosBegin = nPos + 6

   nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(34)))

   sInputName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))

   nPosFile = InstrB(nDataBoundPos, biData, CByteString("filename="))

   nPosBound = InstrB(nPosEnd, biData, vDataBounds)

   If nPosFile <> 0 And  nPosFile < nPosBound Then

    Dim oUploadFile, sFileName

    Set oUploadFile = New UploadedFile

    nPosBegin = nPosFile + 10

    nPosEnd =  InstrB(nPosBegin, biData, CByteString(Chr(34)))

    sFileName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))

    oUploadFile.FileName = Right(sFileName, Len(sFileName)-InStrRev(sFileName, "\"))



    nPos = InstrB(nPosEnd, biData, CByteString("Content-Type:"))

    nPosBegin = nPos + 14

    nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))

    oUploadFile.ContentType = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))

    nPosBegin = nPosEnd+4

    nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2

    oUploadFile.FileData = MidB(biData, nPosBegin, nPosEnd-nPosBegin)

    If oUploadFile.FileSize > 0 Then Files.Add LCase(sInputName), oUploadFile

   Else

    nPos = InstrB(nPos, biData, CByteString(Chr(13)))

    nPosBegin = nPos + 4

    nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2

    If Not mcolFormElem.Exists(LCase(sInputName)) Then mcolFormElem.Add LCase(sInputName), CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))

   End If



   nDataBoundPos = InstrB(nDataBoundPos + LenB(vDataBounds), biData, vDataBounds)

  Loop

 End Sub



 'String to byte string conversion

 Private Function CByteString(sString)

  Dim nIndex

  For nIndex = 1 to Len(sString)

     CByteString = CByteString & ChrB(AscB(Mid(sString,nIndex,1)))

  Next

 End Function



 'Byte string to string conversion

 Private Function CWideString(bsString)

  Dim nIndex

  CWideString =""

  For nIndex = 1 to LenB(bsString)

     CWideString = CWideString & Chr(AscB(MidB(bsString,nIndex,1)))

  Next

 End Function

End Class



Class UploadedFile

 Public ContentType

 Public FileName

 Public FileData



 Public Property Get FileSize()

  FileSize = LenB(FileData)

 End Property



 Public Sub SaveToDisk(sPath)

  Dim oFS, oFile

  Dim nIndex



  If sPath = "" Or FileName = "" Then Exit Sub

  If Mid(sPath, Len(sPath)) <> "\" Then sPath = sPath & "\"



  Set oFS = Server.CreateObject("Scripting.FileSystemObject")

  If Not oFS.FolderExists(sPath) Then Exit Sub

  Set oFile = oFS.CreateTextFile(sPath & FileName, True)

  ' output mechanism modified for buffering
  oFile.Write BufferContent(FileData)



  oFile.Close

 End Sub



 Public Sub SaveToDatabase(ByRef oField)

  If LenB(FileData) = 0 Then Exit Sub

  If IsObject(oField) Then

   oField.AppendChunk FileData

  End If

 End Sub



End Class

%>

The upload.asp file also includes a buffering.inc file. The content of this file is as follows.

<%
' Original Code written by: Robbert Nix
' Adapted and Modified by: Will Bickford
' Date: 12/20/2002
' Email: wbic16@hotmail.com
' From: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=4&txtCodeId=7110

Function BufferContent(data)
 Dim strContent(64)
 Dim I

 ClearString strContent

 For I = 1 To LenB(data)
  AddString strContent,Chr(AscB(MidB(data,i,1)))
 Next

 BufferContent = fnReadString(strContent)
End Function

Sub ClearString(part)
 Dim index

 For index = 0 to 64
  part(index)=""
 Next
End Sub

Sub AddString(part,newString)
 Dim tmp
 Dim index

 part(0) = part(0) & newString

 If Len(part(0)) > 64 Then
  index=0
  tmp=""

  Do
   tmp=part(index) & tmp
   part(index) = ""
   index = index + 1
  Loop until part(index) = ""

  part(index) = tmp
 End If
End Sub

Function fnReadString(part)
 Dim tmp
 Dim index

 tmp = ""

 For index = 0 to 64
  If part(index) <> "" Then
   tmp = part(index) & tmp
  End If
 Next

 FnReadString = tmp
End Function
%>

So , with our MDD and two files , buffering.inc & Upload.asp, what do we do next. Well into your IIS folder structure and create the following , “C:\inetpub\wwwroot\UploadFiles” copy the .inc & asp file into it. Next create the folder that will store the files. We used “C:\temp\test”. Now all you should need to do is to open up your MDD file in professional and run the mdd. If everything has been entered correctly you will get the following screen.


select a file , and the click upload , if everything has worked you will see this , and if you look in your “C:\temp\test” folder you will see your file. It will have been given a new name and extension, but that can easily be changed if you need it.

You can get at the full set of working files in the www.SmarterDataCollection.com/Forum Happy uploading !!!

6 thoughts on “Upload File example.”

  1. This is a nice article. I’ve always had to use an Iframe with a static cgi script that appended the ID number or serial id to the uploaded file. This certainly simplifies things a lot.

    Thanks for sharing!

  2. I’d really like to see how we might be able to use this upload script in our clustered environment where our web server is separated from our application server by a firewall. Specifically, it would be great if we could provide the ability to allow users to use this upload functionality but have their uploaded files sent to the application server inside the firewall, rather than the web server.

    I messed around a bit with a few different ideas, like trying to upload the file by passing it through the SyncWebService (part of the mobile Interviewer application), but I wasn’t successful.

    I’d also like to see an option for multiple file upload too.

    Thanks, so much. Love this site and use if often!

    • Hi Mark, Off the top of the head try this , I will try and test it also as soon as I can. On every IIS machine point the uploadFiles URL to the FMROOT folder of a specified project. ( make it the User Folder for the project or the shared folder ) Then you should be able to just use Administrator to download the files. I see if I can put a multi file upload example together also. That sounds like a nice little project / article.

Leave a Comment

%d bloggers like this: