N342 Home Work 2 - Project Start

Modified

Note

  1. IE caches files by default which can prevent opening of a later version. The effect is particularly noticeable during repeated tests with an ASP file that has been changed but is not opened because of a cached version.

    The solution is to require IE to check for new versions on every visit to a page. In IE:

    Tools | Internet Options | Temporary Internet Files | Settings | Every Visit to Page


     

  2. When running your ASP, receive error message about "Site may be down, try again later. Etc." IE, by default, does not display errors from a Web server.

    Turn OFF friendly error messages by, in IE:

    Tools | Internet Options | Advanced | Browsing | Uncheck "Show friendly HTTP error messages

 

Overview 

The assignment is for familiarization with the project basics and how to build components in a moderately complex Web system.

The project discussion presented the partial logic for registration and logging of stock traders, Registration.asp and Login.asp, these are to be completed. Also necessary is a function to log the current trader out, Logout.asp. 

Project parts - There are three main parts:

  1. ASP - The logic written in JavaScript.
  2. XML/HTML - The user interface written in JavaScript/HTML/XML/XSL, assumed provided (i.e. by N341 students).
  3. Database - The data stored in a relational database.

 

Starting the Project

  1. Download project files and extract to a directory named W:\N342. A subdirectory named Project will contain the project files.

    For students in N341, do N341 work in the N341 directory and N342 work in the N342 directory. Otherwise you will go insane, not totally but do keep the work separate.

    View demo of basic project functionality.
     

  2. Enter the browser address of: iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Welcome.xml
  3. Register.
  4. Login.
  5. Back up.
  6. Log out.
  7. That's all it does for now.

Starting the homework

The project partially works to perform the basic steps to:

  1. register
  2. log in
  3. log out

a user.

Project.mdb - The file that holds all the data base tables.

View demo of database use.

To familiarize yourself with it, do the following:

  1. Open Project.mdb in Access.
  2. Open the Trader table. It should appear similar to that at right.
  3. Note the ID and Logged fields.
    • Logged is checked, indicating that trader Me is logged in.
    • Unchecking Logged will effectively log trader Me out.
    • Remember - this is very useful to force the logout of a trader.
  4. View the demo on using Access to debug your program.
  5. Register a new trader with the Trader table open. Refresh All to see the results.

Registration.asp - Users must register first. Still to be completed for trader registration is:

  1. Verify that password and amount have been entered.
  2. Redirect to the following Web pages for the appropriate conditions:
    1. User password missing - userpasswordMissing.xml
    2. Amount missing - amountMissing.xml
  3. Insert into the Trader table password and amount.

Step 1

  • Starting  - Generally our interest is in the ASP logic and databases so its makes sense to focus on those first.
  1. Open FrontPage and select W:\N342\Project\Registration.asp
  2. Click the Code tab at bottom left.
  • Test for parameter missing - The registration ASP currently only tests for username parameter missing, bold in listing below. We need to test amount and password parameters also.
  1. Copy and duplicate that line.
  2. Modify to test for password parameter.
  3. Change:
    • Response.Redirect("usernameMissing.xml"); to
    • Response.Redirect("userpasswordMissing.xml");
  4. Save.
  5. Enter the browser address of: iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Welcome.xml
  6. Attempt to register with a new user name but no password. You should receive an error message.

 

Registration.asp
<%@ Language=JScript%>
<%	
// Test username !defined || username empty

    if(Request("username").Count == 0 || Request("username")=="") 
       Response.Redirect("usernameMissing.xml");                                   

   var username = Request("username");
   conn = Server.CreateObject("ADODB.Connection");
   conn.Mode = 3;
   conn.Open ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" + 
                      Server.MapPath("Project.mdb"));
   rs = conn.Execute( "SELECT ID FROM Trader where ID='"+username+"' ");

   if (rs.EOF) {
    conn.Execute( "Insert into Trader (ID) values ('"+username+"');");
    conn.Close();
    Response.Redirect("login.xml?"+username);
  }
  else {
    conn.Close();
    Response.Redirect("usernameInuse.xml?"+username);
 }
%>

 

User Interface - Note that not all necessary user interface files are provided.

For example, the following two files are the user interface for user password missing errors. While it may seem overly complex to have two files, an XML file to invoke the HTML, it provides a way to implement a consistent and modular user interface separate from the ASP programming. We'll see how later.

userpasswordMissing.xml
<?xml-stylesheet type="text/xsl" 
               href="userpasswordMissing.htm"?>
<top>
</top>
userpasswordMissing.htm
<h1>User password missing</h1>

 

Step 2

The following two files are the user interface for amount missing errors.

amountMissing.xml
<?xml-stylesheet type="text/xsl" 
               href="amountMissing.htm"?>
<top>
</top>
amountMissing.htm
<h1>Amount missing</h1>
  1. Repeat Step 1 but for amount. Redirect to amountMissing.xml
  2. Enter the browser address of: iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Welcome.xml
  3. Attempt to register with a new user name and password but not amount. The "Amount Missing" error message should display.

 

Database tables - Project.mdb is the data base name containing all the project tables. Nearly all ASP programs examine one or several tables to maintain Web site functions. Registration.asp uses the Trader table that holds personal information on each registered trader. New trader information (i.e. ID, password, amount) must be inserted into the Trader table.

Step 3

  • Starting  - The key part of the ASP logic is to manage databases. Familiarize yourself with the database tables using Access.
    1. Open Access and the file Project.mdb
    2. Open Trader table

     

  • Registration.asp - Registration tests that username is not already in the Trader database table by:

var username = Request("username");
rs = conn.Execute( "SELECT ID FROM Trader where ID='"+username+"' ");
if (rs.EOF) {

If EOF then a new user is registering. New user name of 'Fred' would be inserted into the Trader database table by:

conn.Execute( "Insert into Trader (ID) values ('Fred');");

The username parameter is inserted by:

conn.Execute( "Insert into Trader (ID) values ('"+username+"');");
 

  • Database tables - Insert password of 'SECRET' for each user.
    1. Change:
      • conn.Execute( "Insert into Trader (ID) values ('"+username+"');");  to
      • conn.Execute( "Insert into Trader (ID, PASSWORD) values ('"+username+"', 'SECRET');");
         
    2. Save.
    3. Enter the browser address of: iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Welcome.xml
    4. Register with a new user name.
    5. In Access check the Trader table. Close and reopen Trader table to observe changes.
       
  • Insert - Change the SQL Insert from inserting SECRET to use the password and amount parameters for inserting into the PASSWORD and BALANCE fields of the database.

 

Debugging SQL

Writing correct SQL using parameters is sometimes tricky because the SQL is invisible when executed. The following shows how to display SQL to verify it is correctly formed when executed.

In the following username is a variable.

   var username = Request("username");
   rs = conn.Execute( "SELECT ID FROM Trader where ID='" + username + "' ");

The simplest debugging tool is to first display the SQL to the browser rather than executing.

   var username = Request("username");
   Response.Write( "SELECT ID FROM Trader where ID='" + username + "' ");

However, a Response.Redirect() erases the SQL displayed, so comment out any that execute after the Response.Write().

The SQL debugging of the Registration.ASP is then:

<%@ Language=JScript%>
<%
// Test username !defined || username empty

    if(Request("username").Count == 0 || Request("username")=="")
       Response.Redirect("usernameMissing.xml");                                  

   var username = Request("username");
   conn = Server.CreateObject("ADODB.Connection");
   conn.Mode = 3;
   conn.Open ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" +
                      Server.MapPath("Project.mdb"));
   //rs = conn.Execute( "SELECT ID FROM Trader where ID='"+username+"' ");
   Response.Write( "SELECT ID FROM Trader where ID='"+username+"' ");

   if (rs.EOF) {
    //conn.Execute( "Insert into Trader (ID) values ('"+username+"');");
    Response.Write( "Insert into Trader (ID) values ('"+username+"');");
    conn.Close();
    //Response.Redirect("login.xml?"+username);
  }
  else {
    conn.Close();
    //Response.Redirect("usernameInuse.xml?"+username);
 }
%>

The browser should display results of the Response.Write( "SELECT ID FROM Trader where ID='"+username+"' ");.

SELECT ID FROM Trader where ID='Ray'

The script then crashes, displaying an error message because no SELECT was executed, defining rs.

Microsoft JScript runtime error '800a1391'

'rs' is undefined

However, we now know the SQL is correctly formed.

 

Login.asp - The login function has two key unfinished parts:

  1. Verify trader password from database table before logging in the trader, redirect to userpasswordFails.xml if password fails.
     
  2. Replace display of Response.Write error messages with Response.Redirect to specified Web pages. Redirect to the following Web pages for the appropriate conditions:
    1. Response.Write(username+" is not registered."); - User name not registered - redirect to usernameNotregistered.xml
    2. Response.Write(username+" already logged in"); - User name already logged in - redirect to usernameLoggedinAlready.xml
    3. Response.Write(Session("trader")+" logged in"); - Successful login - redirect to manageTrading.xml
    4. Response.Write(Session("trader") + " is logged in. Please logout first."); - Attempt to login as another trader before logging out - redirect to logoutRequired.xml
    5. User password fails - userpasswordFails.xml

Step 4

  1. Don't forget to log out! We are designing the system to allow only one login from a single computer at a time.
  2. Open FrontPage and select W:\N342\Project\Login.asp
  3. Click the Code tab at bottom left.
  • Test for correct password - The login ASP does not currently test that the password is correct or missing.
  1. Find the line (starting near line 14) in Login.asp of:  if (rs.EOF) {...}
     
    • Immediately after the password entered should be verified to match the registered password in the Trader table.

      You will need to compare two strings, rs("PASSWORD") and the entered password.

      The simplest is to convert the entered password to a JavaScript string by:
       

      • var password = Request("password")+"";

      You can then test for equality by: password == rs("PASSWORD")
       

    • If the passwords fail to match, close the database and redirect to userpasswordFails.xml file.
       
    • Otherwise, continue with the statement:

      if(rs("LOGGED").Value) {
       

  2. Test by logging in with a valid password and then with an invalid password.
     
    • You can force logouts by executing:

      iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Reset.asp

 

Session variables - An independent session is started on an IIS server when the first ASP script is executed in a virtual directory. Session variables provide a means of holding the state of each individual session and can be accessed in any ASP script located in the directory or subdirectories of the initial ASP script starting the session.

Bottom line is that session variables are global to all session scripts. 

Login.asp
<%@ Language=JScript%>
<%	
// Test username !defined || username empty
 if(Request("username").Count == 0 || Request("username")=="")
   Response.Redirect("usernameMissing.xml");

 var username = Request("username")+"";	// Convert Request("username") to string
 conn = Server.CreateObject("ADODB.Connection");
 conn.Mode = 3;
 conn.Open ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" + 
                    Server.MapPath("Project.mdb"));
 rs = conn.Execute("SELECT * FROM Trader where ID='"+username+"'");
	
 if (rs.EOF) {
    conn.Close();
    Response.Write(username+" is not registered.");
 }
 else {
    if(rs("LOGGED").Value) {
      Response.Write(username+" already logged in");
      conn.Close();
    }
    else {
      if(Session("trader")==undefined) {            
        conn.Execute("Update Trader SET LOGGED=true where ID='"+username+"';");
        conn.Close();

        Session("trader")=username;        
        Response.Write(Session("trader")+" logged in");
      }
      else
        Response.Write(Session("trader") + " is logged in. Please logout first.");
    }
 }
%>
 
Logout.asp - Logging out the current trader out requires:
  1. Determining the current trader - use the Session("trader") variable.
  2. Updating the Trader table LOGGED field for the current trader to false.
  3. Removing the current trader session variable - use Session.Abandon
  4. Redirect to logoutSuccessful.xml at execution end.

Still to be completed is:

  1. Delete records from the Cart table for the logged in trader - use the Session("trader") variable. The shopping cart module that inserts records into the Cart table will be added later. For testing that appropriate records are deleted, use Access to manually insert several records into the Cart table; the ID field should match that of the current trader; the Session("trader") value.
  2. Redirect to logoutSuccessful.xml at execution end in place of Response.Write("Logged out") message.

Step 5

  1. Open FrontPage and select W:\N342\Project\Logout.asp
  2. Click the Code tab at bottom left.
  • Delete Cart records - Logout.asp currently logs out traders using an Update to set the Trader table Logged field to false for the Session("trader") variable.
  1. Add another conn.Execute statement to Delete records from the Cart table for the Session("trader") variable.
    • The Cart table holds uncommitted stock trades for all traders; all records for the only current trader must be deleted.
    • This statement must be between the conn.Open and conn.Close statements.
  2. Redirect to logoutSuccessful.xml at execution end in place of Response.Write("Logged out") message.
     
  3. Test by:
    • logging in as a trader,
    • in Access, add records to the Cart table for that trader,
    • logging out and verifying the Cart table records are deleted.

 

Logout.asp
<%@ Language=JScript%>
<%	
  conn = Server.CreateObject("ADODB.Connection"); 
  conn.Mode = 3;
  conn.Open ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" + 
                    Server.MapPath("Project.mdb"));
  conn.Execute("Update Trader SET LOGGED=false where ID='"+Session("trader")+"';");
  conn.Close();
  Session.Abandon;		// Release all session variables
  Response.Write("Logged out");
%>

Assignment

Complete:

  1. Registration.asp

    Completed after Step 3 above.
     

  2. Login.asp

    Verify trader password from database table before logging in the trader, redirect to userpasswordFails.xml if password fails. Completed after Step 4 above.

    Replace display of Response.Write error messages with Response.Redirect to specified Web pages. Redirect to the following Web pages for the appropriate conditions:

    1. Response.Write(username+" is not registered."); - User name not registered - redirect to usernameNotregistered.xml
    2. Response.Write(username+" already logged in"); - User name already logged in - redirect to usernameLoggedinAlready.xml
    3. Response.Write(Session("trader")+" logged in"); - Successful login - redirect to manageTrading.xml
    4. Response.Write(Session("trader") + " is logged in. Please logout first."); - Attempt to login as another trader before logging out - redirect to logoutRequired.xml
    5. User password fails - userpasswordFails.xml
       
  3. Logout.asp

    Completed after Step 5 above.

Testing

Test each ASP script for all possible cases, there is a relatively small number (invalid password, no credit card, etc.). The ASP script must be executed on an IIS server. For example, the following executes the Login.asp script directly rather than from the Login.xml form, passing the two parameters "username" and "password" to the script:

Remember to refresh the page each time as the browser caches the most recent page.

Problems

Likely problems are:

  1. When running your ASP, receive error message about "Site may be down, try again later." IE, by default, does not display errors from a Web server. Turn OFF friendly error messages by, in IE:

    Tools | Internet Options | Advanced | Browsing | Uncheck "Show friendly HTTP error messages"

     

  2. Refresh the browser - Remember the browser caches the output which may be stale.
     
  3. Script errors - Use the Response.Write("Got here in the Login Script"); tracing of execution.
     
  4. SQL - Getting the " and ' right is difficult. For example:
    • conn.Execute("Update Trader SET LOGGED=false where ID='"+Session("trader")+"';");

    When you get an execution error message, try writing it out by:

    • Response.Write("Update Trader SET LOGGED=false where ID='"+Session("trader")+"';");
       
  5. Already logged in - Usually due to the scripts leaving the session variables or databases tables in a conflicting state; for the trader, the session is logged in but the database is logged out.
    • run Reset.asp
    • or manually change the Trader table in Access to log traders out by unchecking the Logged field.
       
  6. Session variables - The session (i.e. starting from the time a file in the Project directory is accessed) expires after some set amount of time, depending upon the Global.asa file or IIS settings, can be as short as 1 minute. When the session the session times out, the Session("trader") variable is undefined.
     
  7. Database tables - The state of the project is held in database tables. When your scripts go awry the tables can be left in a conflicting state. Use Access to edit the tables to the proper state.
     
  8. Errors related to OPEN of database - In Access, open the Project.mdb database, select Tools. Database Utilities..., Compact and Repair Database.

Turn in - Due before class on the date listed in the syllabus.

  1. OnCourse Drop Box
    1. Compress the Project folder containing the homework files.
      • In Windows Explorer, right-click on the Project folder.
      • Click Send to then click Compressed (zipped) Folder.
      • Project.zip will be created.
    2. Upload Project.zip to your N342 OnCourse Drop Box using the Display Name of HW2.
       
  2. Web server
    1. Map and copy to W: drive.
    2. Test in IE. The Welcome.xml is a default page.
      • In browser address enter: http://iu-uits-eiwp1.ads.iu.edu/username/N342/Project/Welcome.xml
  3. Email