How to upload files to a Web server by using ASP (299692)
The information in this article applies to:
- Microsoft Active Server Pages
- Microsoft Internet Information Server 4.0
- Microsoft Internet Information Server 5.0
This article was previously published under Q299692
For a Microsoft Visual Basic .NET version of this article, see 315832.
SUMMARY This article describes how to enable your Web server to
receive file transfers from Microsoft Active Server Pages (ASP) pages by using
a server-side Microsoft COM+ component.
back to the top
Requirements- Microsoft Windows 2000 with Microsoft Internet Information
Server 5.0 (IIS) installed and configured
- If your development computer is a different computer than
the server, you must have a valid network or Internet connection to the server that
hosts the ASP pages.
back to
the top Microsoft Visual Basic 6 Project Setup and Code- Start Visual Basic, and then start a new ActiveX DLL
project.
- Name the project
ASPFileUpload.
- Change the name of Class1 to
File.
- On the Project menu, click References.
- In the References dialog box, click to select the following options, and then click OK:
- Visual Basic For Applications
- Visual Basic runtime objects and procedures
- Visual Basic objects and procedures
- OLE Automation
- COM+ Services Type Library
- Microsoft Active Server Pages Object Library
- Microsoft Scripting Runtime
- On the Project menu, click ASPFileUpload Properties.
- In the Project Properties dialog box, click to select Unattended Execution and Retained In Memory, and then click OK.
- Paste the following code to File.cls:
Option Explicit
Const ERR_INVALID_FILENAME = vbObjectError + 1000
Const ERR_INVALID_TARGET = vbObjectError + 1001
Const ERR_FILE_EXISTS = vbObjectError + 1002
Const ERR_UPLOAD_CALLED = vbObjectError + 1003
Const VB_ERR_PATH_NOT_FOUND = 76
Private m_objContext As ObjectContext
Private m_objRequest As ASPTypeLibrary.Request
Private m_strTarget As String
Private m_strFileName As String
Private m_blnOverWrite As Boolean
Private m_blnUploaded As Boolean
Private m_lngTotalBytes As Long
'All other form elements go here.
Private m_formCol As Scripting.Dictionary
Implements ObjectControl
Private Function ObjectControl_CanBePooled() As Boolean
ObjectControl_CanBePooled = False
End Function
Private Sub ObjectControl_Activate()
Set m_objContext = GetObjectContext()
Set m_objRequest = m_objContext("Request")
Set m_formCol = New Scripting.Dictionary
End Sub
Private Sub ObjectControl_Deactivate()
Set m_objContext = Nothing
Set m_objRequest = Nothing
Set m_formCol = Nothing
End Sub
Public Sub Upload()
Const DEFAULT_CHUNK_SIZE = 262144 '256kb
Dim bytBeginOfChunk() As Byte
Dim bytEndOfChunk() As Byte
Dim bytBeginOfName() As Byte
Dim bytEndOfName() As Byte
Dim bytBeginOfFile() As Byte
Dim bytEndOfFile() As Byte
Dim bytBeginOfValue() As Byte
Dim bytEndOfValue() As Byte
Dim bytName() As Byte
Dim bytValue() As Byte
Dim bytThisChunk() As Byte
Dim bytFileName() As Byte
Dim lngBeginOfChunk As Long
Dim lngEndOfChunk As Long
Dim lngBeginOfAttribute As Long
Dim lngEndOfAttribute As Long
Dim lngBeginOfValue As Long
Dim lngEndOfValue As Long
Dim blnEndOfData As Boolean
Dim lngChunkSize As Long
Dim lngBytesLeft As Long
Dim lngFileNum As Long
Dim strFileName As String
On Error GoTo UploadErr
If Uploaded Then
Err.Raise ERR_UPLOAD_CALLED, App.Title, "The Upload method has already been called."
End If
bytBeginOfChunk = StrConv("-----------------------------", vbFromUnicode)
bytEndOfChunk = StrConv("-----------------------------", vbFromUnicode)
bytBeginOfName = StrConv("name=", vbFromUnicode) & ChrB(34)
bytEndOfName = ChrB(34)
bytBeginOfFile = StrConv("filename=", vbFromUnicode) & ChrB(34)
bytEndOfFile = ChrB(34)
bytBeginOfValue = ChrB(13) & ChrB(10) & ChrB(13) & ChrB(10)
bytEndOfValue = ChrB(13) & ChrB(10) & StrConv("-----------------------------", vbFromUnicode)
'Initialize the chunk size.
If m_objRequest.TotalBytes <= DEFAULT_CHUNK_SIZE Then
lngChunkSize = m_objRequest.TotalBytes
Else
lngChunkSize = DEFAULT_CHUNK_SIZE
End If
'Get the chunk from the request object.
bytThisChunk = m_objRequest.BinaryRead(CVar(lngChunkSize))
'Initialize the value.
lngBeginOfChunk = 1
'Repeat until the end of the data.
Do While Not blnEndOfData
'Begin the chunk.
lngBeginOfChunk = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfChunk) + UBound(bytBeginOfChunk)
'Get name of the item.
lngBeginOfAttribute = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfName) + UBound(bytBeginOfName) + 1
lngEndOfAttribute = InStrB(lngBeginOfAttribute, bytThisChunk, bytEndOfName)
bytName = MidB(bytThisChunk, lngBeginOfAttribute, lngEndOfAttribute - lngBeginOfAttribute)
'Get the value of the item.
lngBeginOfValue = InStrB(lngEndOfAttribute, bytThisChunk, bytBeginOfValue, vbBinaryCompare) + UBound(bytBeginOfValue) + 1
lngEndOfValue = InStrB(lngBeginOfValue, bytThisChunk, bytEndOfValue, vbBinaryCompare)
If lngEndOfValue = 0 Then
'The item extends the past current chunk.
bytValue = MidB(bytThisChunk, lngBeginOfValue, lngChunkSize)
Else
'The item value exists in the current chunk.
bytValue = MidB(bytThisChunk, lngBeginOfValue, lngEndOfValue - lngBeginOfValue)
End If
If UCase(StrConv(bytName, vbUnicode)) = "FILE" Then
lngBeginOfAttribute = InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfFile, vbBinaryCompare) + UBound(bytBeginOfFile) + 1
lngEndOfAttribute = InStrB(lngBeginOfAttribute, bytThisChunk, bytEndOfFile, vbBinaryCompare)
bytFileName = MidB(bytThisChunk, lngBeginOfAttribute, lngEndOfAttribute - lngBeginOfAttribute)
If UBound(bytFileName) < 0 Or UBound(bytValue) < 0 Then
Err.Raise ERR_INVALID_FILENAME, App.Title, "Invalid File Name."
End If
If Me.Target = "" Then
Err.Raise ERR_INVALID_TARGET, App.Title, "Invalid Target."
End If
'Use the original file name.
If Me.FileName = "" Then
'Trim the path from the file name.
While InStrB(1, bytFileName, StrConv("\", vbFromUnicode), vbBinaryCompare) > 0
bytFileName = MidB(bytFileName, InStrB(1, bytFileName, StrConv("\", vbFromUnicode)) + 1)
Wend
'Set the property.
Me.FileName = StrConv(bytFileName, vbUnicode)
'Convert the byte to Unicode.
strFileName = Me.Target & Me.FileName
Else
strFileName = Me.Target & Me.FileName
End If
'Check for overwrite.
If Me.OverWrite Then
'This is the hack check. Make sure that wildcard characters cannot be used.
If Not InStr(1, strFileName, "*") Then
If FileExists(strFileName) Then
Kill strFileName
End If
Else
Err.Raise ERR_INVALID_FILENAME, App.Title, "The specified file name appears to be invalid."
End If
Else
If FileExists(strFileName) Then
Err.Raise ERR_FILE_EXISTS, App.Title, "The file already exists."
End If
End If
lngFileNum = FreeFile
Open strFileName For Binary Access Write As #lngFileNum
'Write the file to the destination directory.
Put #lngFileNum, , bytValue
'This chunk is empty. Therefore, get a new chunk.
lngBytesLeft = m_objRequest.TotalBytes - lngChunkSize
'Start the chunking machine.
Do While lngBytesLeft > 0
'Get a new chunk.
bytThisChunk = m_objRequest.BinaryRead(CVar(lngChunkSize))
lngEndOfValue = InStrB(1, bytThisChunk, bytEndOfValue, vbBinaryCompare)
If lngEndOfValue > 0 Then
'The item value exists in the current chunk.
bytThisChunk = MidB(bytThisChunk, 1, lngEndOfValue - 1)
End If
'Append the chunk to the file.
Put #lngFileNum, , bytThisChunk
lngBytesLeft = lngBytesLeft - lngChunkSize
If lngBytesLeft < lngChunkSize Then
lngChunkSize = lngBytesLeft
End If
Loop
Close #lngFileNum
TotalBytes = FileLen(strFileName)
' Exit Do
Else
If UCase(StrConv(bytName, vbUnicode)) = "SAVEAS" Then
Me.FileName = StrConv(bytValue, vbUnicode)
Else
'form field other than file, such as textboxes
If UBound(bytValue) > 0 And UBound(bytName) > 0 Then
m_formCol.Add StrConv(bytName, vbUnicode), StrConv(bytValue, vbUnicode)
Else
m_formCol.Add StrConv(bytName, vbUnicode), ""
End If
End If
End If
'Get the next chunk.
lngBeginOfChunk = lngEndOfValue
If InStrB(lngBeginOfChunk, bytThisChunk, bytBeginOfName, vbBinaryCompare) = 0 Then
blnEndOfData = True
End If
Loop
Uploaded = True
Exit Sub
UploadErr:
If Err.Number = VB_ERR_PATH_NOT_FOUND Then
Err.Raise ERR_INVALID_TARGET, App.Title, "The Target specified does not exist."
Else
Err.Raise Err.Number, Err.Source, Err.Description
End If
End Sub
Public Property Get Form() As Collection
Set Form = m_formCol
End Property
Public Property Get FileName() As String
FileName = m_strFileName
End Property
Public Property Let FileName(ByVal strNewValue As String)
If Uploaded Then
Err.Raise ERR_UPLOAD_CALLED, App.Title, "The Upload method has already been called."
Else
m_strFileName = strNewValue
End If
End Property
Public Property Get OverWrite() As Boolean
OverWrite = m_blnOverWrite
End Property
Public Property Let OverWrite(ByVal blnNewValue As Boolean)
If Uploaded Then
Err.Raise ERR_UPLOAD_CALLED, App.Title, "The Upload method has already been called."
Else
m_blnOverWrite = blnNewValue
End If
End Property
Private Property Get Uploaded() As Boolean
Uploaded = m_blnUploaded
End Property
Private Property Let Uploaded(ByVal blnNewValue As Boolean)
m_blnUploaded = blnNewValue
End Property
Public Property Get Target() As String
Target = m_strTarget
End Property
Public Property Let Target(ByVal NewValue As String)
If Uploaded Then
Err.Raise ERR_UPLOAD_CALLED, App.Title, "The Upload method has already been called."
Else
m_strTarget = NewValue
End If
End Property
Private Function FileExists(ByVal FileName As String) As Boolean
On Error GoTo FileExistsErr
FileLen FileName
FileExists = True
Exit Function
FileExistsErr:
If Err.Number = VB_ERR_PATH_NOT_FOUND Then
FileExists = False
End If
End Function
Public Property Get TotalBytes() As Long
TotalBytes = m_lngTotalBytes
End Property
Private Property Let TotalBytes(ByVal NewValue As Long)
m_lngTotalBytes = NewValue
End Property
- Compile the project
back to the top
ASP Code- Paste the following code to an editor such as Notepad or
Microsoft Visual Interdev, and then save it as
PostFile.asp:
<%@ Language=VBScript %>
<html>
<head>
</head>
<body>
<form enctype="multipart/form-data" action="uploadfile.asp" method="post" name="main1">
<input name="file" type="file" size="50">
<INPUT type="text" id=text1 name=text1><INPUT type="text" id=text2 name=text2>
<input name="submit" type="submit" value="Upload">
</form>
</body>
</html>
- Copy the following code to an editor such as Notepad or
Visual Interdev, and then save it as UploadFile.asp:
<%@ Language=VBScript %>
<%
'//////////////////////////////////////////////////////////////////////////////////
'// ASPFileUpload.File API
'//
'// Properties
'// FileName
'// - Read/Write
'// - The file will be saved with this file name.
'// - This property can only be set before calling Upload.
'// - If no value is specified, the original file name
'// - in the HTTP post will be used.
'//
'// OverWrite
'// - Read/Write
'// - This property can only be set before calling Upload.
'// - If set to false and if the destination file exists, an error
'// - is raised. The default value is False.
'//
'// Target
'// - Read/Write
'// - The file will be written to this folder.
'// - This property can only be set before calling Upload.
'// - There is no default value for this property and it is required.
'//
'// Form
'// - ReadOnly
'// - Scripting.Dictionary object
'// - Can access a specific item by using aspfileupload.Form("item").
'// - Acts like the asp form collection.
'// - Can enumerate all values in a collection with for each.
'// - Only filled after the Upload method is called.
'//
'// Methods
'// Upload
'// - This method parses the HTTP Post and writes the file.
'//
'// Other
'// - ASPFileUpload requires COM+
'// - Any call to the Request.Form() collection will cause the Upload
'// method to fail as the method references the Binary contents of the
'// Request object through the Request.BinaryRead method.
'// - Also, if you access a variable in the Request collection without
'// specifying the subcollection that it belongs to, the Request.Form collection
'// may be searched. This causes an error in the Upload method.
'//
'//////////////////////////////////////////////////////////////////////////////////
Dim strMsg 'As String
' On Error Resume Next
dim fuFile
set fuFile = server.CreateObject("aspFileupload.file")
'Set the destination folder.
fuFile.Target = "C:\TEMP\AspFileUpload\"
fuFile.Upload
If Err.number = 0 Then
strMsg = fuFile.FileName & " was uploaded successfully."
Else
strMsg = "An error occurred when uploading your file: " & Err.Description
End If
for each o in fuFile.Form
Response.Write o & "<BR>"
next
Response.Write fuFile.Form.item("text1") & " : " & fuFile.Form.item("text2")
' Response.Write Request.Form("test")
set fufile = nothing
%>
<html>
<head></head>
<body>
<%=strMsg%>
</body>
</html>
back to the top
Set Up the Server- Create a folder on the Web server that will receive the
uploaded files, such as
C:\TEMP\AspFileUpload.
- Copy the ASPFileUpload.dll file to the Web server, and then
register it by using the following command at the command prompt:
regsvr32 PathToDLL\ASPFileUpload.dll - Apply file permissions (Write access) for the users who you want to be able to upload the files.
- Click Start, point to
Settings, and then click Control
Panel.
- In Control Panel, click Administrative
Tools, and then click Component Services to open
Component Services in the Microsoft Management Console (MMC).
- Expand the Component Services node, the
Computers node, the My Computer node, and the
COM+ Applications node.
- Right-click the
node, point to New, and then click
Application.
- In the Install or Create a New Application dialog box, click Create an empty application,
name the application, make sure that you click to select Server
application, and then click Next.
- In the Set Application Identity dialog
box, click This User, and then type the credentials for the
appropriate user account. The user account must have Write access to the folder
that will receive the uploaded file.
- Click Finish.
- Expand the node that you have just created for this
application.
- Right-click the nod, point to New, and
then click Component.
- Click Install new components,
and locate the folder where you have saved and registered the .dll file, click
the file, click Next, and then click
Finish.
- Copy the Postfile.asp file and the Uploadfile.asp file to
your Web root folder. By default, the Web root folder is
C:\Inetpub\Wwwroot.
- Edit the target folder of Uploadfile.asp to reflect the
folder that you created in step 1. The target folder assignment is located in
the following line of code:
fuFile.Target = "C:\TEMP\AspFileUpload\"
back to
the top Upload a File- In a Web browser, open the Postfile.asp page at the
following URL:
http://YourWebServer/Postfile.asp - Select a file that you want to upload, and then click
Upload.
- Check your upload folder. The file that you uploaded appears in this folder.
back to the top
Troubleshooting- If you do not type a file name, and if you try to submit
the Postfile.asp page, you receive a generic, server-side error message. You
may want to modify the code to provide a more friendly error message on either
the client side or on the server side.
- If you require high volume upload capacity, Microsoft
recommends that you buy or build a compiled, multithreaded component that can
more efficiently handle the load than this Visual Basic component.
- A potential security risk exists whenever you allow users
to upload files to your Web server. This is especially true if your server is
on the Internet, and if you allow anonymous uploads. You must correctly
configure Windows permissions and IIS user authentication to make sure that you
give users only the access that they require. This is important so that you do not
allow users a way to gain access by bypassing the security controls of your
system.
back to the top
Modification Type: | Minor | Last Reviewed: | 7/8/2005 |
---|
Keywords: | kbASPObj kbCodeSnippet kbConfig kbDeployment kbfile kbFSO kbGuidelines kbhowto kbSample kbScript kbSecurity kbServer kbsetup kbWebServer KB299692 kbAudDeveloper |
---|
|