asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Using the ServerZip ASP Component
By Alex Homer
Rating: 2.8 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    This Issue

    In this issue of 15 Seconds we feature the final chapter, by Alex Homer, of a new book called 'Professional Active Server Pages 2 Programming' from Wrox Press (ISBN 1-861001-26-6) due for publication in early March 1998. The chapter as a whole is a case study examining how Active Server Components can be built from existing components, so as to achieve high levels of functionality reasonably quickly. This section describes how the finished component can be used.

    ServerZip Component

    As an intrepid programming detective, you've now discovered almost all there is to know about the ServerZip component all that remains of our adventure story is the obligatory happy ending. Even though you may not have built the component yourself, there's nothing to stop you using it in your own pages. In fact, there are now so many Active Server Components available that you may never have to build your own.

    For some idea of the range of Active Server Components that are available, visit 15 Seconds' Component Section

    In the remainder of this chapter, we'll be putting the ServerZip component to work. You can download the finished component from http://rapid.wrox.co.uk or http://www.rapid.wrox.com. Included with it are a series of sample pages that demonstrate the features it provides. These are designed to allow you full freedom to experiment with all the properties and methods that the component provides.

    Warning
    Allowing anonymous remote users free access to all the properties and methods is probably not a good idea. In your ASP applications, you'll want to expose only a selected set of properties and methods over the Web, and verify and set the others within your ASP script code. You can also limit the available options using the SZConfig utility that is provided with the component.

    The ServerZip Sample Pages

    In the section about the component interface, earlier in this chapter, we listed all the available properties and methods of the component. Here, we'll be using all these in a series of four sample pages:

    Step 1 - Setting the file listing properties to display files on the server.

    Step 2 - Displaying the files list and setting options for the doZip() method.

    Step 3 - Creating a zip file, and setting the options to delete old files.

    Step 4 - Deleting old download directories and returning to Step 1.

    To run these pages, you must first have installed the ServerZip component (instructions are provided in the download file). Copy the samples from the installation directory into a directory somewhere below the WWWRoot directory on your server, and make sure that this directory has Script Execute access permission.

    Setting the fileListing Properties

    The first page, szexamp.htm, is not an ASP page at all, it just contains the controls where the user can set the values to be used for listing files:

    Figure 1

    The controls are on a <FORM>, whose ACTION is the file szfiles.asp. We use METHOD="POST" (as recommended by HTML 4.0), and so we'll be able to collect the values in the next page using the ASP Forms collection:
    
    <FORM ACTION=szfiles.asp METHOD="POST">
    <TABLE WIDTH=100% CELLPADDING=5>
    ...
    <TR>
     <TD>Directory name (physical or virtual):</TD>
     <TD><INPUT TYPE="TEXT" NAME=txtFileRoot SIZE=25></TD>
     <TD><B>= fileListRoot</B></TD>
    </TR>
    <TR>
     <TDText/HTML to go before filename: </TD>
     <TD><INPUT TYPE="TEXT" NAME=txtBeforeHTML SIZE=25 VALUE="<OPTION>"></TD>
     <TD ALIGN="LEFT"><B>= beforeFileHTML</B></TD>
    </TR>
    <TR>
     <TD>Text/HTML to go after filename: </TD>
     <TD><INPUT TYPE="TEXT" NAME=txtAfterHTML SIZE=25></TD>
     <TD><B>= afterFileHTML</B></TD>
    </TR>
    <TR>
     <TD>File type specification:</TD>
     <TD><B>fileListing( 
      <INPUT TYPE="TEXT" NAME=txtFileType SIZE=8 VALUE="*.*"> )</B></TD>
     <TD><B>Method parameter</B></TD>
    </TR>
    <TR>
     <TD COLSPAN=3 ALIGN="RIGHT"><INPUT TYPE="SUBMIT" VALUE="Next >"></TD>
    </TR>
    </TABLE>
    </FORM>
    
    
    The last row of the table is the SUBMIT button, which sends the values of all the controls to the file szfiles.asp.

    Listing files and Setting the doZip() Options

    The remaining three pages are all Active Server Pages .asp files. Because the ServerZip component works best with buffering turned on, we've included the following line at the beginning of each page:

    
    <% Response.Buffer = True %>
    
    
    In the page szfiles.asp, we use the component to create a list of files in a <SELECT> control this is why the default value of the beforeFileHTML property control in the previous page was set to <OPTION>. Here's the code that creates the new instance of our component, sets its properties, and calls the fileListing() method—again, all the controls are on a <FORM>, whose ACTION this time is the file szdozip.asp:
    
    <FORM ACTION=szdozip.asp METHOD="POST">
    ...
    <SELECT MULTIPLE SIZE=10 NAME=selSourceList>
    <%
    Set objSZ = Server.CreateObject("Stonebroom.ServerZip")
    objSZ.fileListRoot = Request.Form("txtFileRoot")
    objSZ.beforeFileHTML = Request.Form("txtBeforeHTML")
    objSZ.afterFileHTML = Request.Form("txtAfterHTML")
    intFiles = objSZ.fileListing(Request.Form("txtFileType"))
    Set objSZ = Nothing
    %>
    </SELECT>
    
    
    We also use the return value of the fileListing() method to show how many files were listed:
    
    ...
    Listed <% = intFiles %> files.
    ... 
    
    
    Finally, we store the value of the fileListRoot property in a HIDDEN control, so that we can pass it on to the next page where we'll need it again:
    
    ...
    <INPUT TYPE="HIDDEN" NAME="hidListPath" VALUE="<% = Request.Form("txtFileRoot") %>">
    ...
    
    
    And here's the result. You can see we found three files:

    Figure 2

    The remainder of this page is just more HTML controls on the same <FORM> as the <SELECT> list. When the user clicks the Next button, the values of these controls will be passed on to the next page, szdozip.htm.

    Creating a Zip File

    Now we come to the most complicated page. This has to collect all the values sent from the previous page, and execute the doZip() method of the component. However, things are made more complex by the fact that we're allowing the user to select files using the list we provided. Alternatively, they can type a physical or virtual file specification into the text box below the list. So the first thing our code has to do in the szdozip.asp page is figure out what the sourceFileList property should be.

    The value sent from the txtSourceList control contains the text typed into the sourceFileList text box. If there was a value there, we simply use it as the sourceFileList property. However if it was empty, we know that we have to use the items selected in the list instead. This is a multiple-select list (it includes the MULTIPLE attribute in its opening HTML tag), so the value could be more that one filename. In this case, the browser returns all the selected entries as a single string with each one separated from the rest by a comma.

    Handling Multiple-Select Lists

    Our ASP code has to break this list up into a format suitable for the component's sourceFileList property, and add the path that the user provided for the file listing to each one. This is why we carried it forward in the hidden control from the previous page. If the path is a virtual one we can only use one file, and this will be the first one selected. However if it's a physical path, we have to collect all the files from the list. The first part of our code decides which type of values we're dealing with:

    
    <%
    strSourceList = Request.Form("txtSourceList") 'value from text box
    If Len(strSourceList) = 0 Then 'use files selected in list
    'the file list directory they used to get the list of files
    'is carried forward from a hidden control in the form:
    strListPath = Request.Form("hidListPath")
    If InStr(strListPath, ":") Or InStr(strListPath, "\") Then
     blnPhysical = True 'its a physical path
     If Right(strListPath, 1) <> "\" Then 
      strListPath = strListPath & "\"
     End If
    Else 'its a virtual path
     blnPhysical = False 
     If Right(strListPath, 1) <> "/" Then 
      strListPath = strListPath & "/"
     End If
    End If
    
    'All the items selected in the list box are comma-delimited 
    'in a single string from the form. We get this string with:
    strFileList = Request.Form("selSourceList")
    If Instr(strFileList, ",") Then 'several files selected
     'get the first one into strSourceList
     strSourceList = strListPath & Left(strFileList, Instr(strFileList, ",") - 1)
    Else 'a single file selected
     strSourceList = strListPath & strFileList
     strFileList = ""
    End If
    
    ...
    
    
    Our component expects any files whose names include a space to be enclosed in double quotes (ASCII character 34). We'll do this now for the one file we've already got in strSourceList:
    
    ...
    If InStr(strSourceList, " ") Then 
     strSourceList = Chr(34) & strSourceList & Chr(34)
    End If
    ...
    
    
    If we're dealing with a physical path and have a list of files, we can carry on splitting each one off the original string, wrapping them up in double quotes where necessary, and adding them to the strSourceList string. Each entry in strSourceList needs to be the full path and name of a file we want to include in the zip file, separated from its neighbors by a single space character:
    
    ...
    If (blnPhysical) And (Len(strFileList)) Then
     'physical directory, so we can get the rest of the files
     strFileList = Trim(Mid(strFileList, Instr(strFileList, ",") + 1))
     strNextFile = strListPath & Left(strFileList, Instr(strFileList, ",") - 1)
     If InStr(strNextFile, " ") Then 
      strNextFile = Chr(34) & strNextFile & Chr(34)
     End If
     'component expects a source file list delimited with spaces
     strSourceList = strSourceList & " " & strNextFile
     Do While Instr(strFileList, ",") 
      strFileList = Trim(Mid(strFileList, Instr(strFileList, ",") + 1))
      If Instr(strFileList, ",") Then 'more files to come
       strNextFile = strListPath & Left(strFileList, Instr(strFileList, ",") - 1)
      Else 'this is the last one in the list
       strNextFile = strListPath & strFileList
      End If
      If InStr(strNextFile, " ") Then
       strNextFile = Chr(34) & strNextFile & Chr(34)
      End If
      strSourceList = strSourceList & " " & strNextFile
     Loop
    End If
    End If
    Response.Write "Source file list is <B>" & strSourceList & "</B><P>"
    
    ...
    
    

    Setting the Script Time-Out Value

    The last step in the code above is to write the value of the strSourceList into the page, so that the user can see what we think they selected. Before we actually start zipping the files, however, there is one other task. Because the operation may take a while to complete, we'll change the script execution timeout from the default 20 seconds to a higher value:

    
    ...
    Server.ScriptTimeOut = 600 
    ...
    
    

    Setting the Component Properties

    Finally, we're ready to create the component object and set the properties. Notice how we use the value of the checkboxes (which return "on" if checked or nothing if not checked) to set the Boolean properties of the component. We also need to convert the compression rate value into a number before we try and apply it to the component:

    
    ...
    Set objSZ = Server.CreateObject("Stonebroom.ServerZip")
    objSZ.sourceFileList = strSourceList
    objSZ.zipFileName = Request.Form("txtZipFile")
    objSZ.virtualTargetRoot = Request.Form("txtTargetRoot")
    objSZ.encryptCode = Request.Form("txtEncryptCode")
    objSZ.compressionRate = CInt(Request.Form("selCompressRate"))
    objSZ.recurseDirs = (Request.Form("chkRecurseDirs") = "on")
    objSZ.deleteOriginalFiles = (Request.Form("chkDeleteOriginals") = "on")
    ...
    
    

    Checking if the Component is Busy

    Everything is now ready to start the zip process, but before we go leaping headlong into it we need to remember that the component does not allow concurrent operations. To get round this, we use the zipIsBusy property that it exposes, and wait up to a couple of minutes for it to become available:

    
    ...
    If objSZ.zipIsBusy Then
     Response.Write "Waiting to access the component ...<P>"
     Response.Flush
     'force display by the browser with 2 Write/Flush operations
     Response.Write ""
     Response.Flush
     'then wait up to two mins for component to become available
     intWaitUntil = (Minute(Now) + 2) Mod 60
     Do While (objSZ.zipIsBusy) And (Minute(Now) <> intWaitUntil)
     Loop
    End If
    If objSZ.zipIsBusy Then
     Response.Write "Sorry, the component is too busy at present.<P>"
     Response.Flush
    Else 'OK to do the zip
     blnWorked = objSZ.doZip()
    End If
    Set objSZ = Nothing 
    %>
    
    
    And here's the result. Notice that the file is placed in a hyperlink ready to collect. The status bar shows the path to it, complete with the unique subdirectory within the target directory where it was placed:

    Figure 3

    The remaining section of this page provides the controls for deleting old files and directories that should have already been collected. You can see that the 'Virtual target root' text box already contains the path that we used for this zip file. This saves having to type it in if you want to clear old directories from the same virtual root. It's achieved with the value of the virtualTargetRoot property that we used earlier in the page:
    
    <INPUT TYPE="TEXT" NAME="txtTargetRoot" SIZE=25 VALUE="<% = Request.Form("txtTargetRoot") %>">
    
    

    Using Other Zip Properties

    In the previous example we only typed in values for the required properties of the component, in the controls on the page, leaving the others at their defaults. However we can also provide an encryption code, include any subdirectory contents, and delete the original files:

    Figure 4

    You can see here that we've entered a physical path to the source files, and included the wildcard file specification *.* (all files). We've also turned on the 'Subdirectory files' and 'Delete originals' options. To prevent you deleting files by accident, a warning dialog pops up when you turn on the 'Delete originals' option. This is done by some client-side JavaScript code written in the page:
    
    <INPUT TYPE="CHECKBOX" NAME=chkDelete onClick="deleteConfirm()">
    ...
    <SCRIPT LANGUAGE="JAVASCRIPT">
    <!--
    function deleteConfirm() {
    if (document.forms[0].elements["chkDeleteOriginals"].checked)
    { var strMesg = 'WARNING: You have elected to delete the '
    + 'original files once compression is complete. '
    + 'Make sure that you do not include files that '
    + 'you do not want to delete.';
    alert(strMesg);
    }
    }
    //-->
    </SCRIPT>
    
    
    However, we've also set the Registry value DisableDeleteOriginalFiles to "1" on our server using the supplied SZConfig utility, so when the zip operation takes place an error message is inserted into the page and the originals are not deleted:

    Figure 5

    This time, you see the nine source files being compressed one by one, and when complete the resulting zip file can be collected. When viewed in a zip file manager, you can see the single subdirectory and its contents that were within the source directory:

    Figure 6

    And because we provided an encryption key for the encryptCode property, we can’t unzip the files without it:

    Figure 7

    Deleting Old Unique Download Directories

    The final page in our examples is used to remove old downloaded zip files and the uniquely-named directories that they reside in. We only need to worry about two properties for this, one of which defaults to a sensible value if not specified.

    The bottom section of the page szdozip.asp that we've just been working with contains the two controls for the virtualTargetRoot and daysOldToDelete properties. These values are passed to the page szdelete.asp when the Next button is clicked, and we use these to set the properties of the component:

    
    
    
    
    
    
    This removes the old directories and files, and places a confirmation message in the page. We use the value returned by the deleteOldFiles method to show how many directories were deleted:
    
    
    <%
    ...
    <B>ServerZip</B> reports that it deleted<B> <% = intFiles %> </B>
    unique directories and their contents within the virtual root<B>
    <% = Request.Form("txtTargetRoot") %>
    ...
    %>
    
    
    
    Here's how it looks in the browser:

    Figure 8

    At the bottom of the page is a button that returns us to the original szexamp.htm page, so that we can go round again. Rather than use client-side script to load the page, we've made the button a SUBMIT button, and placed it on a form whose ACTION is the ordinary HTML page we want to load. In order for this to work, we have to break with the recommendations of HTML 4 and use METHOD="GET". If we use "POST", the server will report an error:
    
    
    ...
    <FORM ACTION="szexamp.htm" METHOD="GET">
    <TABLE WIDTH=100%>
    <TR>
    <TD ALIGN="RIGHT"><INPUT TYPE="SUBMIT" VALUE="Next >"></TD>
    </TR>
    </TABLE>
    </FORM>
    ...
    
    
    

    Summary

    And that's it. In this chapter, we've explored the background, requirements, techniques and implementation of a custom Active Server Component, and seen how it can be used with ASP script in our applications. Developing components is not really an Active Server Pages topic, but if you understand how they are built, how they generally work and interact with ASP, and the limitations that they have to work under, it makes it easier to decide when a component is a good solution to your requirements.

    We've used Visual Basic in this chapter to build our component, with the intention of making it easy to follow how it works, and what it's doing behind the scenes. Of course, any other language that can create COM-enabled objects, such as C++, Java, Delphi, etc. can be used instead. In our case, where all the real processing is done by a legacy DLL, Visual Basic proves plenty fast enough to act as the interface and the glue that links Active Server Pages with the internal objects inside our component.

    Copyright

    This text is owned and copyrighted by Wrox Press Limited, UK and USA. No parts may be stored, copied or distributed without the prior permission of the publishers. For more information contact Anthea Elston (antheae@wrox.com), or visit http://www.wrox.com or http://rapid.wrox.co.uk.

    Copyright 1998 - Wrox Press Limited, UK and USA.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers