Link to home
Start Free TrialLog in
Avatar of tomstraw
tomstraw

asked on

How To Change File Name On Front End Automatically In An ASP Upload

I am working with a client now who wants to upload files to his web server using ASP/VBScript.  I found a nice little script to do it quick and dirty at

http://www.freeaspupload.net/

However, client is now (justifiably) worried about duplicate file names; this script doesn't handle them--it simply overwrites the old file.

Is there a way I can customize file names on the front end so as to avoid duplicate file names?  I want to avoid installing components on the web server b/c the server admin is uncomfortable doing it, and it's potentially costly, etc.  Plus, we just had a whole lot of trouble with permisions to get dynamic DB app working, so I hate to make another server request unless I absolutely have to!

I am pretty good with Javascript, but not so great with ASP/VBScript (I let DW 8 do that for me).  I tried creating a new Recordset on the page and customizing the form field value with a dynamically generated unique field in the DB (such as ID or firstname = lastname), but I kept making the VBScript angry and crashing the whole app! (Variety of errors--but mainly "Must use only one instance of % on ASP page"--pretty obvious to me what it means but not savvy enough with VBScript to fix!)

Any help would be appreciated.  I have a feeling this might be solvbed with something fairly simple, but I am too "in the middle of things" right now to see clearly!

Here is the code I took from freeaspload.net, with just a few lines tailored for my purposes.  The code is one page that serves as both the form and the processor of form.  It is published on a web server running IIS.

<%@ Language=VBScript %>
<%
option explicit
Response.Expires = -1
Server.ScriptTimeout = 600
%>
<!-- #include file="freeASPUpload.asp" -->
<%


' ****************************************************
' Change the value of the variable below to the pathname
' of a directory with write permissions, for example "C:\Inetpub\wwwroot"
  Dim uploadsDirVar
  uploadsDirVar = "C:\Inetpub\wwwroot\wn\db"
' ****************************************************

' Note: this file uploadTester.asp is just an example to demonstrate
' the capabilities of the freeASPUpload.asp class. There are no plans
' to add any new features to uploadTester.asp itself. Feel free to add
' your own code. If you are building a content management system, you
' may also want to consider this script: http://www.webfilebrowser.com/

function OutputForm()
%>
    <form name="frmSend" method="POST" enctype="multipart/form-data" action="uploadTester.asp" onSubmit="return onSubmitForm();">
      <B>File names:</B><br>
    File 1: <input name="attach1" type="file" size=35><br>
    <br>
      <!-- These input elements are obviously optional and just included here for demonstration purposes -->
      <B>Additional fields (demo):</B><br>
      Enter a number: <input type="text" name="enter_a_number"><br>
    Checkbox values: <input type="checkbox" value="1" name="checkbox_values">-1 <input type="checkbox" value="2" name="checkbox_values">-2<br>
      <!-- End of additional elements -->
    <input style="margin-top:4" type=submit value="Upload">
    </form>
<%
end function

function TestEnvironment()
    Dim fso, fileName, testFile, streamTest
    TestEnvironment = ""
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    if not fso.FolderExists(uploadsDirVar) then
        TestEnvironment = "<B>Folder " & uploadsDirVar & " does not exist.</B><br>The value of your uploadsDirVar is incorrect. Open uploadTester.asp in an editor and change the value of uploadsDirVar to the pathname of a directory with write permissions."
        exit function
    end if
    fileName = uploadsDirVar & "\test.txt"
    on error resume next
    Set testFile = fso.CreateTextFile(fileName, true)
    If Err.Number<>0 then
        TestEnvironment = "<B>Folder " & uploadsDirVar & " does not have write permissions.</B><br>The value of your uploadsDirVar is incorrect. Open uploadTester.asp in an editor and change the value of uploadsDirVar to the pathname of a directory with write permissions."
        exit function
    end if
    Err.Clear
    testFile.Close
    fso.DeleteFile(fileName)
    If Err.Number<>0 then
        TestEnvironment = "<B>Folder " & uploadsDirVar & " does not have delete permissions</B>, although it does have write permissions.<br>Change the permissions for IUSR_<I>computername</I> on this folder."
        exit function
    end if
    Err.Clear
    Set streamTest = Server.CreateObject("ADODB.Stream")
    If Err.Number<>0 then
        TestEnvironment = "<B>The ADODB object <I>Stream</I> is not available in your server.</B><br>Check the Requirements page for information about upgrading your ADODB libraries."
        exit function
    end if
    Set streamTest = Nothing
end function

function SaveFiles
    Dim Upload, fileName, fileSize, ks, i, fileKey

    Set Upload = New FreeASPUpload
    Upload.Save(uploadsDirVar)

      ' If something fails inside the script, but the exception is handled
      If Err.Number<>0 then Exit function

    SaveFiles = ""
    ks = Upload.UploadedFiles.keys
    if (UBound(ks) <> -1) then
        SaveFiles = "<B>Files uploaded:</B> "
        for each fileKey in Upload.UploadedFiles.keys
            SaveFiles = SaveFiles & Upload.UploadedFiles(fileKey).FileName & " (" & Upload.UploadedFiles(fileKey).Length & "B) "
        next
    else
        SaveFiles = "The file name specified in the upload form does not correspond to a valid file in the system."
    end if
      SaveFiles = SaveFiles & "<br>Enter a number = " & Upload.Form("enter_a_number") & "<br>"
      SaveFiles = SaveFiles & "Checkbox values = " & Upload.Form("checkbox_values") & "<br>"
end function
%>

<HTML>
<HEAD>
<TITLE>Test Free ASP Upload</TITLE>
<style>
BODY {background-color: white;font-family:arial; font-size:12}
</style>
<script>
function onSubmitForm() {
    var formDOMObj = document.frmSend;
    if (formDOMObj.attach1.value == "" && formDOMObj.attach2.value == "" && formDOMObj.attach3.value == "" && formDOMObj.attach4.value == "" )
        alert("Please press the browse button and pick a file.")
    else
        return true;
    return false;
}
</script>

</HEAD>

<BODY>

<br><br>
<div style="border-bottom: #A91905 2px solid;font-size:16">Upload files to your server</div>
<%
Dim diagnostics
if Request.ServerVariables("REQUEST_METHOD") <> "POST" then
    diagnostics = TestEnvironment()
    if diagnostics<>"" then
        response.write "<div style=""margin-left:20; margin-top:30; margin-right:30; margin-bottom:30;"">"
        response.write diagnostics
        response.write "<p>After you correct this problem, reload the page."
        response.write "</div>"
    else
        response.write "<div style=""margin-left:150"">"
        OutputForm()
        response.write "</div>"
    end if
else
    response.write "<div style=""margin-left:150"">"
    OutputForm()
    response.write SaveFiles()
    response.write "<br><br></div>"
end if

%>



</BODY>
</HTML>
Avatar of Rouchie
Rouchie
Flag of United Kingdom of Great Britain and Northern Ireland image

It's probably easier to edit freeASPUpload.asp directly, because this file contains all the logic for saving.
Make a copy first and then try this:

Open freeASPUpload.asp and find the code that says this:

Public Sub Save(path)
    Dim streamFile, fileItem

    if Right(path, 1) <> "\" then path = path & "\"

    if not uploadedYet then Upload

    For Each fileItem In UploadedFiles.Items
      Set streamFile = Server.CreateObject("ADODB.Stream")
      streamFile.Type = 1
      streamFile.Open
      StreamRequest.Position=fileItem.Start
      StreamRequest.CopyTo streamFile, fileItem.Length
      streamFile.SaveToFile path & fileItem.FileName, 2
      streamFile.close
      Set streamFile = Nothing
      fileItem.Path = path & fileItem.FileName
     Next
  End Sub

This is the logic that does the saving, so we can expand it to check for the existing of the same file before saving.  If a file already exists, then an error is shown and no file is saved.  Otherwise the file is saved as before.   Select the above code block and paste the following over the top, replacing what was there before:

Public Sub Save(path)
    Dim streamFile, fileItem
    if Right(path, 1) <> "\" then path = path & "\"
    if not uploadedYet then Upload

    Dim newFileName
    newFileName = fileItem.FileName
    dim fs
    set fs=Server.CreateObject("Scripting.FileSystemObject")

    For Each fileItem In UploadedFiles.Items
      if fs.FileExists(path & newFileName) then
         response.write("<span class=""color:#ff0000;"">" & newFileName & " exists and could not be saved; please rename and try again.</span>")
      else
         Set streamFile = Server.CreateObject("ADODB.Stream")
         streamFile.Type = 1
         streamFile.Open
         StreamRequest.Position=fileItem.Start
         StreamRequest.CopyTo streamFile, fileItem.Length
         streamFile.SaveToFile path & newFileName, 2
         streamFile.close
         Set streamFile = Nothing
         fileItem.Path = path & newFileName
      end if
    Next
End Sub
Avatar of tomstraw
tomstraw

ASKER

Rouchie,

many thanks for fast response.  I only had time to try it REAL quickly this AM, and it returned this error:

Microsoft VBScript runtime error '800a01a8'

Object required: 'fileItem'

/wn/freeASPUpload.asp, line 56

The line in reference is

newFileName = fileItem.FileName

At a glance, I have no idea why error is returned, b/c it looks like Object is specified, but again, I am rushed right now.  I will look at it again when I get into office, but if you have any ideas in meantime, I'd be much, much obliged!
ASKER CERTIFIED SOLUTION
Avatar of Rouchie
Rouchie
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Rouchie, you are officially "da man."  Many Many thanks.  The only (slight) downside is that I really don't know exactly "how" you got it to work, but I am going to pore (pour?) over it for awhile and see if I can't digest it.  I really do try to learn how the problem was solved, rather than just harvest solutions from the experts and implement them without knowing what's "really" going on, etc.  For example, I recently had an SQL challenge that I posted on this site, got a lot of great help figuring it out, and now I actually feel like I could hand-code a solution the next time I come across the requirement!  But this one? Whew . . . I was pretty out of my league, and I was up against a tough deadline!  So a million thanks again for pulling me out of the fire!  The great thing about design and development is that you truly do learn something new every day--or at least get reminded that there's so much more you can know! :-)
>> Rouchie, you are officially "da man."

Thanks - much appreciated :-)

>> I really don't know exactly "how" you got it to work

See my comments after each line of code:

Public Sub Save(path)
    Dim streamFile, fileItem
    if Right(path, 1) <> "\" then path = path & "\"
    if not uploadedYet then Upload
    Dim newFileName, fs ' declare new empty variables
    set fs=Server.CreateObject("Scripting.FileSystemObject") ' set 1 variable to be the file system object (which has the power to manipulate files)
    For Each fileItem In UploadedFiles.Items ' loop through each file that's been uploaded when the page was submitted
      newFileName = fileItem.FileName ' assign the file name to check to be this file's name
      if fs.FileExists(path & newFileName) then ' use the file system object to check the current file's existence
         response.write("<span class=""color:#ff0000;"">" & newFileName & " exists and could not be saved; please rename and try again.</span>") ' the file exists so through an error
      else
         Set streamFile = Server.CreateObject("ADODB.Stream") ' do the normal save stuff that was there before
         streamFile.Type = 1
         streamFile.Open
         StreamRequest.Position=fileItem.Start
         StreamRequest.CopyTo streamFile, fileItem.Length
         streamFile.SaveToFile path & newFileName, 2
         streamFile.close
         Set streamFile = Nothing
         fileItem.Path = path & newFileName
      end if
    Next
End Sub