Bannerco-op Banner Exchange Bannerco-op Banner Exchange
The BannerCo-Op - 1-1 Exchange + Cash

logo.GIF (5678 bytes)

<Appendix A: "Case Study: Building an Interactive Product" / ASP Book Home Page / Appendix C: "Delivering an Interactive Introduction Service">

howto.GIF (910 bytes)

...establish a Membership-based Community.

CREATE & PUBLISH

Create a Web Page.
Active Server Pages (ASP) Book.
Meta tags tutorial.
Publish a Web Page.
Submit the page to the search engines.

ADVERTISING

Advertise on your page.

MAKE CASH

Earn cash with your page.
Earn cash while surf.
Send me your suggestion about this site and win a FREE E-BOOK about web site promotion. Click here to download the book (438Kb). I will send you the password needed to install the book. Thank you! For your suggestion:

Feel free to send!


Our Sponsors Today:

oneandonlywebmaster.gif (1012 bytes)

utrade.gif (4221 bytes)

love.GIF (1572 bytes)

Click here for www.bannerco-op.com!

Appendix B

Establishing a Membership-based Community


  • Designing a database: Member table

    Due to the importance of a database in managing a membership-based community, starting with a careful design of the information to be collected proves invaluable in the subsequent development steps.

  • Establishing a New Member

    Establishing a New Account means implementing a New Account sign up process and recording the information necessary to track that New Member.

  • Managing logon and validation

    In developing a membership-based Web site, it is critical that you provide an efficient method to log a user onto the site and to validate a user's membership status.

  • Users maintaining their own account information

    To manage a membership-based site without incurring unreasonable administrative expenses, the site must provide facilities that enable users to maintain their own account information.

Building a membership-based community immediately demands certain features and functionality requirements that should be provided as part of the site. These features almost always require a database and generally include a New Account sign up process, logon/validation, and a series of account maintenance and administrative features.

You should begin the design process by assessing the membership database required for collecting the necessary membership information and for tracking user activity. The membership- related database tables will store user information for customizing the user's experience at the site, for evaluating current status and permissions, and for assessing appropriate billing. These critical features highlight the importance of properly design. The design decisions will ensure that the required fields of information are available and the performance requirements for the database are met.

Generally, membership means a database. Any other method of tracking membership-related information is unreasonably costly and inefficient.

Once a well-designed data structure has been established, the following sections detail the features necessary to manage the membership-based environment including the New Account sign up process, logon/validation features, and users account maintenance. Establishing a New Account sign up process provides a good starting point, as it often highlights required features that may have been overlooked in the initial design process. The logon and account validation code should have a focus on efficiency and security for the site. The logon and validation components primarily focus on controlling which aspects of the site users can reach, and they provide an important mechanism to ensure security and fee collection features of the site are properly enforced.

As you turn your development activities toward managing account status and history tracking, as well as account maintenance and administrative activities, your focus turns toward automating the administrative activities involved in account upkeep and reporting requirements.

Database Design-Membership Tables

The database design process for creating the Membership table provides a system for defining various types of information to be used by the system. Minimally, the information collected should include a unique ID to track the various members. In practice, additional information will be collected in several categories:

  • System Status information: unique ID, account status, date stamps, and more
  • Administrative information: billing-related information and other account management information
  • Profile-related information: information updated by the members themselves

In the Love@1st Site Introduction Service (Service), we undertook a comprehensive design phase, involving the key constituencies involved in creating, financing, and using the site to determine the necessary information to track about the user community. The information includes system information, administrative information, e-mail services related flags, Member Profile data, and a profile of the member's Ideal Mate.

The table information illustrated as follows shows field information based on a Microsoft Access table; this maintains consistency with the presentation of this book and was the environment used during testing of the site. The production version of this site is Microsoft SQL Server.

System Information

From the system level, we determined a series of fields of information we had to collect to manage the member at the site. The specific fields of the Membership table, which can be found on the book's Web site are listed in Table B.1:

Table B.1 The Database Structure of the Primary System Information of the Membership Table

Field Name Data Type Size Description
MemberID Number (Long) 4 Core account number-hidden from user
SignOnID Number (Long) 4 Session ID-temporary value for tracking
Download Number (Long) 4 Flag for downloading information to accounting system
ReferredBy Text 25 Information on accounts referred from partner Websites
InactivateReason Number (Long) 4 Reason flag for inactive status
CompletedProcess Yes/No 1 Flag to show successful completion of New Account sign up and billing process

Some of fields utilized for system-related functionality are classified as Administrative fields to illustrate that they can be updated by site administrators through Active Server Pages. Together, System and Administrative fields form the set of information used by the system to manage members. System information is updated only by the core program itself and not by members or administrative users of the site.

Administrative Information

Administrative information, like System information, provides key data for tracking and managing the member, the key distinction being that Administrative information can be edited by administrative users of the site. Allowing key membership-related information to be administered by site users is a fundamental method for distributing control and management tasks away from the code writer to the site users. This creates the mechanism for avoiding continual upgrades to code. The key administrative fields for the Membership table are listed in Table B.2.

The key value of editable information will be demonstrated in more depth in the administrative Appendix, as you note the parameter-driven nature of core features ranging from drop-down box options to billing structures.

Table B.2 The Database Structure of the Primary Administrative Information of the Membership Table

Field Name Data Type Size Description
AdmCreateDate Date/Time 8 Initial account creation data
AdmModDate Date/Time 8 Date account last modified
AdmStartDate Date/Time 8 Date paid membership began
AdmExpDate Date/Time 8 Date valid membership status expired
AdmOnlineDate Date/Time 8 Date user last logged onto site
AdmPublic Yes/No 1 Flag denoting searchable account
AdmStatus Number (Long) 4 Status of member account, i.e. active, inactive
Admingraphics Yes/No 1 Graphic images submitted for display by member, a prerequisite for active account status

Profile and General Demographic Account Information

The profile information displays information entered by the users themselves for other members to view. The profile information enables the searching features of the site and allows members to get to know each other while deciding whether or not to introduce themselves. The specific information includes all the fields illustrated in Table B.3.

Table B.3 The Database Structure of Profile and General Demographic Information of the Membership Table

Field Name Data Type Size Description
Pass Text 50 Password for secure access
FName Text 30 First name
LName Text 50 Last name
Address1 Text 150 Address line one
Address2 Text 150 Address line two
City Text 50 City
StateID Text 2 State
Zip Text 20 Zip code
HMPhone Text 30 Home phone number
HMAreaCode Text 3 Home area code (for searching)
WKPhone Text 30 Work phone number
WKAreaCode Text 3 Work area code (for searching)
PublicPhone Number (Long) 4 Flag denoting phone number can be released
Email Text 50 E-mail address
PublicEmail Yes/No 1 Flag denoting e-mail address can be released
Maiden Text 50 Mother's maiden name for validation if password is lost
ProfSex Yes/No 1 Male or female
ProfPrefID Yes/No 1 Preferred sex (can not be altered)
ProfRaceID Number (Long) 4 Ethnic/racial background
ProfRlgnID Number (Long) 4 Religion
Profdob Date/Time 8 Date of birth for custom birthday notes and user validation
ProfHeightF Number (Long) 4 Member height (feet)
ProfHeightI Number (Long) 4 Member height (inches)
ProfBodyID Number (Long) 4 Member body type
ProfStatusID Text 50 Marital status (Married is not an option)
ProfEdID Number (Long) 4 Education level
ProfOcc Text 150 Occupation description
ProfChldNum Number (Long) 4 Number of children
ProfChldExist Number (Long) 4 Flag whether or not member has children
ProfChldNew Number (Long) 4 Interest in having children
ProfSmkgID Number (Long) 4 Smoking status
ProfDrkgID Number (Long) 4 Drinking status
ProfEyeID Text 15 Member's eye color
ProfHairID Text 15 Member's hair color
ProfAct Memo - Member general entry of activities they enjoy
ProfMovie Text 100 Favorite movies
ProfMusic Text 50 Multiple selection list for music IDs
ProfBook Text 100 Last book read
ProfWhat Memo - What are you looking for in a relationship question
ProfQ1ID Number (Long) 4 ID of second parameter-driven question
ProfQ1Info Memo - Answer to parameter-driven question

This profile and demographic information is used to dynamically build profile pages for display to users interested in learning more about a certain member that they find in a search or who requests their introduction.

Automated E-mail Services Flag Information

The Service provides extensive e-mail features for its membership community as a method of communication between members. Members may generate e-mails to other members through the system without the identity of either member being released. And based on profiles and flag selections, the system may automatically generate an e-mail message to notify a member of an introduction request or that someone matching her Ideal Mate profile has joined the membership community. The flags in the Membership table that manage this set of features are included in Table B.4.

Table B.4 The Database Structure of Automatic E-mail Services Flags in the Membership Table

Field Name Data Type Size Description
Eselect Yes/No 1 Send me a message when another member selects me.
Eaccept Yes/No 1 Send me a message when a member I have selected accepts my request.
EGenie Yes/No 1 Send me a message if a member matching my Ideal Mate profile joins.
EGen Yes/No 1 Send me general site announcements of events.
EOK Yes/No 1 Allow members to send me notes after they have selected me.

Microsoft SQL Server's "send mail stored" procedure drives these e-mail services that are executed through database calls by Active Server Pages through the ActiveX Data Object (ADO) component.

Ideal Mate Profile Information

The Ideal Mate-related profile very closely mirrors the Member Profile information and enables a member to customize the search utilities to the profile that she will use most often when searching the system. In addition, the Ideal Mate profile provides a mechanism that enables the system to attempt matching New Members with members already in the system. This automated matching feature sends users e-mail notifications that encourage them to return to the site and provides them with value-added services to facilitate members finding members. The specific fields associated with managing these features are illustrated in Table B.5.

Table B.5 The Database Structure of Ideal Mate Profile Information in the Membership Table

Field Name Data Type Size Description
idlRaceID Number (Long) 4 Ideal Mate race
idlagehigh Number (Long) 4 Ideal Mate age range (high)
idlagelow Number (Long) 4 Ideal Mate age range (low)
idlRlgnID Number (Long) 4 Ideal Mate religion
idlHeightFlag Number (Long) 4 Ideal Mate height above or below flag
idlHeightF Number (Long) 4 Ideal Mate height (feet)
idlHeightI Number (Long) 4 Ideal Mate height (inches)
idlSmkgID Number (Long) 4 Ideal Mate smoking status
idlDrkgID Number (Long) 4 Ideal Mate drinking status
idllocflag Yes/No 1 Ideal Mate location flag, i.e. is location relevant?
idllocarea1 Text 3 Ideal Mate area code if relevant
idllocarea2 Text 3 Ideal Mate area code, number two if relevant

Establishing a New Member

With the table design completed for the Membership table, developing a member sign up process becomes the first step of site creation. This enables the testing users to enter members and to work with the site almost immediately, leading to a clarification of missing information that has to be added to the site.. The New Account sign up process results in five separate Active Server Pages or .asp files. The initial development of the pages focused entirely on functionality, with graphic design and general look enhancement taking place at the very end of the development process.

The five-step New Account process walked the prospective member through the entering of Ideal Mate, Profile, demographic information, billing selection, and payment choices. Whereas the final two steps relating to billing are dealt with extensively in a later chapter, at this point we will explore the creation of a New Account.

New Account: Step 1

The initial page largely presents standard HTML, providing information within a standard form that enables users to enter data and to select options. The only significant use of Active Server Pages features includes the lookup of parameters to populate drop-down lists and the server-side include of a validation .asp file, which will be explored in more detail later in this chapter. This page, however, initiates the session and collects the Ideal Mate information used to initially insert a New Member record in step 2.

Listing B.1 illustrates the Server-Side Include feature and the defaulting of drop-down values for ethnic background.

Listing B.1 NEWACCT1.ASP-First Page in the New Account Sign up Process

<!--#include file="validatenew.asp"-->

<%

  Set Conn = Server.CreateObject("ADODB.Connection")

  Conn.Open("firstsite")

' --------------------------------

' --------------------------------

' Output HTML Area

' --------------------------------

' --------------------------------

%>

...

<tr><td width=20%><font color="#0000A0">

Ethnic Background:</font></td><td width=50%>

<select name="idlraceid" size=1 >

<option checked value="0"><font color="#0000A0">No Preference</font></option>

<%

  Set RS = Conn.Execute("SELECT * FROM AdminParameters where (systypeparam = 1)[ic:ccc] order by colatingorder;")

  Do While Not RS.EOF

%>

<option value="<%=rs("sysparamid")%>"><%=rs("paramvalue")%></option>

<%

  RS.MoveNext

  Loop

  RS.Close

%>

</select></td></tr>

...

The code illustrated in Listing B.1 includes an example of how a parameter table can be used for populating options in the system. This parameter table can then be maintained by site administrators through standard Active Server Pages.

New Account: Step 2

During step 2 the initial account record is created with the add new method. In addition to the Server-Side Include validation in step 1 and the parameter-driven populating of drop-down boxes illustrated in step 1, step 2 checks logon status to ensure that the current user has not already inserted the initial record; then step 2 either does an database insert or simply redisplays the account ID, depending on the logonstatus of the session ID. Listing B.2 illustrates the database insert and user validations done in step 2.

Listing B.2 NEWACCT2.ASP-Inserting the Initial Record with Ideal Mate Information from Step 1 and System/Administrative Defaults for the New Account

<!--#include file="validatenew.asp"-->

<%

  Set Conn = Server.CreateObject("ADODB.Connection")

  Conn.Open("firstsite")

Select Case session("logonstatus")

Case 3 ' Already Past this insert step

msg = "<blink>Please Record your New Member ID:</blink> [ic:ccc]" & session("memberid") & " "

Case 2 ' Proper Status for Insert of New Account

   set rsInsert = Server.CreateObject("ADO.RecordSet")

   'Conn.BeginTrans

   rsInsert.Open "Members", Conn, 3, 3

   rsInsert.AddNew

   rsInsert("SignOnID")   = session.sessionid

   rsInsert("AdmCreateDate")  = Date()

   rsInsert("AdmModDate")  = Date()

   rsInsert("AdmStartDate")   = Date()

   rsInsert("AdmOnlineDate")  = Date()

   rsInsert("AdmPublic")    = 0

   rsInsert("AdmStatus")    = 0

   rsInsert("publicphone")    = 0

   'Testing Uncertain Values

  

   heightF = request.form("idlHeightF")

   heightI = request.form("idlHeightI")

   if heightF = "" then heightF = 0

   if heighti = "" then heightI = 0

   rsInsert("idlRaceID")     = request.form("idlRaceID")

   rsInsert("idlAgeHigh")   = request.form("idlAgeHigh")

   rsInsert("idlAgeLow")     = request.form("idlAgeLow")

   rsInsert("idlRlgnID")     = request.form("idlRlgnID")

   rsInsert("idlHeightFlag")   = request.form("idlHeightFlag")

   rsInsert("idlHeightF")   = heightf

   rsInsert("idlHeightI")   = heighti

   rsInsert("idlSmkgID")    = request.form("idlSmkgID")

   rsInsert("idlDrkgID")     = request.form("idlDrkgID")

   rsInsert("idlLocFlag")   = request.form("idllocflag")

   rsInsert("idlLocArea1") = request.form("idllocarea1")

   rsInsert("idlLocArea2") = request.form("idllocarea2")

   rsInsert("download")    = 0

   rsInsert("stateid")     = "CA"

   rsInsert.Update

   'Conn.CommitTrans

   rsInsert.Close

   sql = "SELECT Members.SignOnID, Members.memberid, Members.AdmCreateDate FROM Members WHERE[ic:ccc] (((Members.SignOnID)=" & session.sessionid & ") AND ((Members.AdmCreateDate)=Date()));"

   Set RS = Conn.Execute(sql)

   msg = "<blink>Please Record your New Member ID:</blink> " & rs("memberid") & " "

   ' ---------------------------------------

   ' Set Session Object with memberid value

   ' ---------------------------------------

     memval = rs("memberid")

     session("memberid") = memval

     session("logonstatus") = 3

     rs.close

End Select

' --------------------------------

' --------------------------------

' Output HTML Area

' --------------------------------

' --------------------------------

%>

...

New Account: Step 3

Step 3 provides an update SQL statement to add additional profile information to the New Members record. To update the record, step 3 performs a series of data evaluations and manipulations to prepare the information for the update statement. Conditional processing such as If/Then statements and For/Next loops are used to evaluate form-based information, and in addition to simple evaluations, a callable string function is invoked for modifying various fields to strip out single and double quotation marks, which can affect the SQL-based update statement.

The code in Listing B.3 illustrates several important features associated with the update of an existing account. In addition to the update of the account record in the database, Listing B.3 also illustrates callable functions and variable testing.

Listing B.3 NEWACCT3.ASP-The Use of a Callable Function, Variable Testing, and Update SQL Statement

<!--#include file="validatenew.asp"-->

<script language=vbscript runat=server>

Function StripChars(txtstring)

   tempstring = ""

   length = Len(txtstring)

   For i = 1 To length

      singlechar = Mid(txtstring, i, 1)

      If singlechar = Chr(34) then

         tempstring = tempstring & Chr(180) & Chr(180)

      ElseIf singlechar = Chr(39) then

         tempstring = tempstring & Chr(180)

      Else

         tempstring = tempstring & singlechar

      End If

   Next

   StripChars = tempstring

End Function

</script>

<%

  Set Conn = Server.CreateObject("ADODB.Connection")

  Conn.Open("firstsite")

  'Set Conn = Session("Conn")

' -------------------------------------------

' Update based on member id in session object

' -------------------------------------------

'Testing Uncertain Values

'--------------------------

OCC = request.form("profocc")

act = request.form("profact")

movie = request.form("profmovie")

music = request.form("profmusic")

book = request.form("profbook")

what = request.form("profwhat")

Q1Info = request.form("profQ1Info")

heightF = request.form("profHeightF")

heightI = request.form("profHeightI")

dob = request.form("profdob")

profhairid = request.form("profhairid")

profeyeid = request.form("profeyeid")

if occ = "" then occ = "NA"

if act = "" then act = "NA"

if movie = "" then movie = "NA"

if music = "" then music = 0

if book = "" then book = "NA"

if what = "" then what = "NA"

if Q1info = "" then Q1info = "NA"

if HeightF = "" then HeightF = 0

if Heighti = "" then HeightI = 0

if dob = "" then dob = "01/01/01"

'------------------------

if request.form("profsex") <> "" then

sql = "UPDATE Members SET"

      sql = sql & " Members.ProfSex =" & request.form("profsex") & ","

      sql = sql & " Members.ProfPrefID =" & request.form("ProfPrefID") & ","

      sql = sql & " Members.ProfRaceID =" & request.form("profRaceID") & ","

      sql = sql & " Members.ProfRlgnID =" & request.form("profRlgnID") & ","

      sql = sql & " Members.Profdob =#" & stripchars(dob) & "#,"

      sql = sql & " Members.ProfHeightF =" & stripchars(HeightF) & ","

      sql = sql & " Members.ProfHeightI =" & stripchars(HeightI) & ","

      sql = sql & " Members.ProfBodyID =" & request.form("profBodyID") & ","

      sql = sql & " Members.ProfStatusID ='" & request.form("profStatusID") & "',"

      sql = sql & " Members.ProfEdID =" & request.form("profEdID") & ","

      sql = sql & " Members.ProfOcc ='" & stripchars(occ) & "',"

      sql = sql & " Members.ProfChldNum =" & request.form("ProfChldNum") & ","

      sql = sql & " Members.ProfChldExist =1," '& request.form("ProfChldExist") & ","

      sql = sql & " Members.ProfChldNew =1," '& request.form("ProfChldNew") & ","

      sql = sql & " Members.ProfSmkgID =" & request.form("ProfSmkgID") & ","

      sql = sql & " Members.ProfDrkgID =" & request.form("ProfDrkgID") & ","

      sql = sql & " Members.ProfEyeID ='" & ProfEyeID & "',"

      sql = sql & " Members.ProfHairID ='" & ProfHairID & "',"

      sql = sql & " Members.ProfAct ='" & stripchars(act) & "',"

      sql = sql & " Members.ProfMovie ='" & stripchars(movie) & "',"

      sql = sql & " Members.ProfMusic ='" & stripchars(music) & "',"

      sql = sql & " Members.ProfBook ='" & stripchars(book) & "',"

      sql = sql & " Members.ProfWhat ='" & stripchars(what) & "',"

      sql = sql & " Members.ProfQ1ID =" & request.form("ProfQ1ID") & ","

      sql = sql & " Members.ProfQ1Info ='" & stripchars(Q1Info) & "' "

      sql = sql & " WHERE (((Members.AdmCreateDate)=Date()) AND"

      sql = sql & " ((Members.memberID)=" & session("memberid") & "))"

      Set rsupdate = Server.CreateObject("ADO.Recordset")

      rsupdate.Open sql, Conn, 3

end if

Set rsStates = Conn.Execute("SELECT StatePostalCode FROM States;")

' --------------------------------

' --------------------------------

sql = "SELECT * FROM Members WHERE MemberID=" & session("MemberID") & ";"

Set rs = Conn.Execute(sql)

%>

Recap of New Account Sign Up Process

The New Account Sign Up process involves the creation of a New Account record; a prospective member's data is carefully entered into the database, tracked, and evaluated for potential matches as the prospective member moves through a series of screens that guides the entry of information. Some of the key Active Server features invoked include:

  • Session ID for tracking state during the initial insert and retrieval of a member record
  • Request Object for gathering data entered in form fields
  • VBScript for the conditional processing related to data validation and manipulation
  • ADO Component for the active use of a database to store information entered

Managing Logon and Validation

Once a New Member Profile has been successfully created and activated by whatever administrative process has been created, a logon process must be created to validate a user's identity. In addition, with a membership paradigm, users who attempt to open an .asp file without logging on must be trapped and routed to a logon screen for validation. At first glance, this process seems to require the use of Windows NT Server's User Manager. After a quick review, however, it becomes clear that managing the authentication process through a database has many benefits over the user manager from maintainability and efficiency perspectives. As a result, I leave the user manager for highly sensitive security issues such as site administration and immediately rely on database lookups for membership authentication.

The components of an effective Logon and Validation model include a logon screen, which can set a session variable for tracking the logon status, and a validation .asp file, which is included at the top of every page and which redirects users to the logon screen if they do not pass a simple check of the logon session variable. These components immediately provide much better security than most solutions found on the Web today. One of the benefits of a session variable is that it only resides at the server. Rather than writing a status with a cookie, which can be "spoofed", the logon status relates to a given Session ID on the browser and, therefore, does not get directly passed over the Internet.

Generally, on the Internet, spoofing refers to creating a transaction where the one computer pretends to the have the address, or identity, of another computer. We use this imagery because with a faked cookie, a computer could send a transaction to the Web server that would lead it to mistakenly assume it was a different computer.

The Logon Process

The logon process can be more or less complicated, depending on your method for authenticating the member. The logon screens should also be candidates for two types of security measures. First, the field in which a password or other type of information is entered should be set as a password so that asterisks are displays in the browser in place of the data entered by the user; second, this screen may also be used with an SSL socket (i.e. HTTPS:// reference) to ensure the encryption of password information as it passes over the network. These security decisions depend on the level of security required at your site.

Secure Sockets Layer (SSL)

SSL provides the most widely used mechanism for securing Web-related information in transit on the Internet. In summary, SSL provides an encryption standard for Web browsers and Web Servers to securely share information.

The initial logon page simply requires a form field for the entry of whatever validation information needs to be submitted.

In addition to the basic data entry fields, our Service displays a system message that explains why the user ended up at this page. The appropriate message string is set to a Session property and subsequently displayed if a failed logon attempt occurs or if the user gets routed to the logon screen from a validation in some other .asp file. In addition, if the Session property used for storing messages is left empty, then the current session is abandoned to enable the user to log on again. Listing B.4 illustrates the code used at the top of the .asp file to check the Session property containing the message and either display the message, if the logon attempt failed, or abandon the current Session and allow a new logon to occur.

Listing B.4 LOGON.ASP-Illustration of Message Display at the Top of the Logon Page

<%  msg = session("msg")

'--------------------------------------'

Output HTML Section

'--------------------------------------

%>

<html><head><title>

Love@1st Site - Interactive Introductions-Logon

</title></head><body bgcolor="#FFFFFF">

<%=msg%>

<%

  If session("msg") = "" then

     session.abandon

  End If

  session("msg") = ""

%>

Once the initial logon request is submitted, the Service begins a comprehensive set of evaluation routines to identify whether or not the logon attempt authenticates the user, and if not, to determine why the authentication attempt failed.

The logon.asp invokes the logoncheck.asp file, which directly outputs nothing. The authentication file simply evaluates the logon attempt and either redirects a successful logon to the start.asp page or sets a message to the session (msg) variable and redirects the user back to the logon.asp page. If a successful logon occurs, the logoncheck.asp also writes an update back to the Membership table to change to the current date/time, the date/time field used for tracking the last time the user logged on to the Service.

The code illustrated in Listing B.5 shows the process for authenticating the user on the Service. The code also handles the different failure conditions that can result by carefully reviewing all possible failures followed by a comprehensive message back to the user.

The logoncheck.asp cannot directly write HTML output because the redirect feature does not function once HTTP headers have been sent (see format of HTTP record for more details about what the headers include). Headers are sent as soon as a response.write event occurs.

Listing B.5 LOGONCHECK.ASP-Authentication Process for Logon

<Script Language=VBScript runat=server>

Function redirect()

  Response.Redirect "logon.asp"

end function

</script>

<%

Set Conn = Server.CreateObject("ADO.Connection")

Conn.Open("firstsite")

'-----------------------------------------------------

'-----------------------------------------------------

'Level 1 Basic Validation Testing

'-----------------------------------------------------

'-----------------------------------------------------

'Test for Entry of Member ID prior to Running Search

'-----------------------------------------------------

if request.form("memberid")="" then ' No Member ID Entered

  session("msg") = "<h3><center>Oops! The Member ID# didn't work.    Try the Member ID# search below.</center></h3>"

  Redirect 'Call Function to Exit Back to Logon Screen

'Run Search

'-----------------------------------------------------

else 'Run Database Lookup

  sql = "SELECT members.admonlinedate, Members.MemberID, members.pass,    Members.FName, Members.LName, Members.AdmExpDate, Members.AdmStatus, Members.InactivateReason,     Members.AdminGraphics, Members.AdmCreateDate FROM Members "

  sql = sql & "WHERE (((Members.MemberID)=" & request.form("memberid") & "));"

  set rs = conn.execute(sql)

end if

'------------------------------------------

'------------------------------------------

'Level 2 Validation Testing

'------------------------------------------

'------------------------------------------

If not rs.eof then

   test = rs("memberid")

   session("memberid") = test

End If

'Member ID Entered Now Run Search for Record

'-------------------------------------------

If rs.eof Then 'No Record Found Bad ID

  rs.close

  session("msg") = "<h3><center>Oops! We couldn't find Member ID# <em>" &    request.form("memberid") & "</em>. Please try again or use our Member ID# [ic:ccc]Search below.</center></h3>"

  Redirect 'Call Function to Exit Back to Logon Screen

'Customer Record Found Now Check Password

'-----------------------------------------

elseif not request.form("password") = rs("pass") then

  rs.close

  session("msg") = "<h3><center>Oops!  Your ID# is okay, but the password didn't work.       (Remember it is case sensitive) Try again.</center></h3>"

  Redirect 'Call Function to Exit Back to Logon Screen

'Check for inactive status

'-------------------------------------------

elseif rs("admstatus") = 0 then

  if rs("CompletedProcess") = 0 then

     rs.close

     session("msg") = "<h3><center>Not Active or Expired Account</center></h3>"

     Redirect 'Call Function to Exit Back to Logon Screen

  end if

'Password OK now check to see if pictures arrived.  They have 30 days.

'--------------------------------------------------------------------- 

elseif (rs("admingraphics") = 0) and (rs("admcreatedate") + 30 < date()) then

  session("msg") = "<center><font color=" & """" & "#FF0000" & """" & ">[ic:ccc]<strong>We have not received your photos yet.  You are not able to   access Member Services until we receive your photos.</strong></font></center>"

  session("scanaction") = "lockout"

  Response.Redirect "scan.asp"

'See if pictures arrived.  After 15 days they get a warning message.

'--------------------------------------------------------------------- 

elseif (rs("admingraphics") = 0) and (rs("admcreatedate") + 15 < date()) then

  session("msg") = "<center><font color=" & """" & "#FF0000" & """" & "><strong>[ic:ccc]We have not received your photos yet.  If we do not receive your photos prior to " & rs("admcreatedate")   + 15 & ", we will remove your access to Member Services.</strong></font></center>"

  session("scanaction") = "warning"

  Response.Redirect "scan.asp"

'-----------------------------------------------------

'-----------------------------------------------------

' Step 3. Success Logon Approved

'-----------------------------------------------------

'-----------------------------------------------------

else

  session("logonstatus") = 1

  session("AdmOnlineDate") = rs("AdmOnlineDate")

  sql = "UPDATE Members SET"

        sql = sql & " Members.AdmOnlineDate = #" & Date() & "#"

        sql = sql & " WHERE Members.MemberID=" & request.form("memberid") & ";"

        set rs2 = conn.execute(sql)

  response.redirect "start.asp"

end if

rs.close

%>

The Validation Checks

Two discrete validation .asps are used in the Service. The first validate.asp file is used in every page with the exception of the New Account pages, while the second validatenew.asp is used on all New Account pages. Both validation pages rely on the Session property named logonstatus.

The New Account validation pages uses the logon status Session property extensively to monitor what point in the New Account process New Members have reached. This file relies on the select case statement to evaluate all possible statuses of the logon status Session property. Currently only Case 0 and 1 are in use. Listing B.6 illustrates the code of the Select Case statement used to evaluate the Logon Status on New Account Pages

Listing B.6 VALIDATENEW.ASP-The Select Case Evaluation of the Logon Status Variable for Users in the New Account Pages

<%

'Set ADO Object variable for use in remainder of page processing

Set Conn = Server.CreateObject("ADODB.Connection")

Conn.Open("firstsite")

Select Case session("logonstatus")

Case 0 'New Session No Status

      session("logonstatus") = 2

Case 1

      session("logonstatus") = 2

Case 2 'New Member in Sign Up Process first page

Case 3 'New Member in Sign Up Process Record Created

Case 4 'New Member in Sign Up Process Error Status

End Select

%>

The standard validate.asp file, which is invoked with a Server-Side Include statement on all other pages, provides evaluations very similar to the validatenew.asp file, with one minor exception: It only takes action if a logon status is 0. Every other status qualifies either as a New Member in process or as a properly logged on member account. The code for this evaluation is illustrated in Listing B.7.

Listing B.7 VALIDATE.ASP-Validation File Included in All .asp Files Other than the New Account Pages

<%

Set Conn = Server.CreateObject("ADODB.Connection")

Conn.Open("firstsite")

Select Case session("logonstatus")

Case 0 'New Session No Status

      session("msg") = "<h3><center> Your are currently not logged in or your [ic:ccc]login has timed out </center></h3> Please logon to continue your session,   sorry for any inconvenience</h4>"

      Response.Redirect "logon.asp"

Case 1 'Authenticated User Properly Logged On

Case 2 'New Member in Sign Up Process first page

Case 3 'New Member in Sign Up Process Record Created

End Select

%>

Recap of Logon and Validation Process

The Logon and Validation process requires a small amount of code and only a couple of .asp files, but based on Server-Side Includes, these files find their way into every single Active Server Page processed for delivery to the client. Although not complex in implementation, this file provides the heart of membership security features and should be carefully put into effect. Some of the key Active Server features invoked include:

  • Custom Session Variable for tracking logon status
  • Response.Redirect feature for re-routing users from any page to the logon.asp
  • VBScript for the conditional processing related to authentication.
  • ADO Component for the active use of a database to look up account information

Users Maintaining their Own Account Information

Implementing a cost-effective, fee-based subscription service requires automating the costly administrative responsibilities that can develop due in part to member account maintenance and site enhancement. As one effective step in controlling these costs and at the same time empowering the user community with additional control and convenience, a site should place as much maintenance responsibility as possible with the end user community. The Introduction Service places extensive maintenance features in the hands of the members. From Ideal Mate settings to billing information, the member has control.
Enabling members to edit these pages simply involves taking the New Account pages and adapting them for update. The primary change involves defaulting all values in the form fields to be populated with a member's currently set information. In addition, these pages will be updated out of order rather than linearly as with the New Account process. Without going into repetitive detail with the editacctX.asp files, in Listing B.8 I will illustrate just the editacct3.asp, which contains Member Information. The key task involves looking up the customer record and ensuring that the member ID of the currently logged on user matches the one used to look up customer information so that no other user can accidentally edit another member's account.

Listing B.8 EDITACCT3.ASP-Member Editing of Account Information Based on Defaulted Form Field Values

<%

  Set Conn = Server.CreateObject("ADODB.Connection")

  Conn.Open("firstsite")

  sql = "SELECT * FROM Members WHERE MemberID=" & session("MemberID") & ";"

  Set rs = Conn.Execute(sql)

  Set rsStates = Conn.Execute("SELECT StatePostalCode FROM States;")

'Testing Uncertain Values

'--------------------------

OCC = request.form("profocc")

act = request.form("profact")

movie = request.form("profmovie")

book = request.form("profbook")

what = request.form("profwhat")

Q1Info = request.form("profQ1Info")

heightF = request.form("profHeightF")

heightI = request.form("profHeightI")

dob = request.form("profdob")

if occ = "" then occ = "NA"

if act = "" then act = "NA"

if movie = "" then movie = "NA"

if book = "" then book = "NA"

if what = "" then what = "NA"

if Q1info = "" then Q1info = "NA"

if HeightF = "" then HeightF = 0

if Heighti = "" then HeightI = 0

if dob = "" then dob = "01/01/01"

%>

<html>

<base href="http://www.1st-site.com/">

<head>

<title>Edit Membership Information</title>

</head>

<form action="editacctupdate.asp" target="_top" method="POST">

<body bgcolor="#FFFFFF" text="#0000A0">

<table border=1 cellpadding=8 cellspacing=0 width=604>

<tr><td>

<p>Changed your home or e-mail address? Want to change

your password? Care to change your e-mail notification

preferences? Modify your information and preferences

below, then click on the Update button. Your changes

will take effect immediately.

</p>

</td>

</tr>

<tr>

<td align="center">

<br>

<br>

<table width=100%>

<tr><td width=30% valign="top">Password:</td><td

colspan=2 width=40% valign="top"><input type=password

size=10 maxlength=10 name="pass"

value="<%=rs("pass")%>"></td></tr>

...

All edit files invoke the one editaccountupdate.asp file illustrated in Listing B.9. This file centralizes all of the update statements into one file to isolate the code associated with updating accounts. This process of organizing .asp files in an intuitive manner for managing your code can provide invaluable support when you need to edit your code. The editaccountupdate.asp simply executes an update sql statement based on the fields entered.

Listing B.9 EDITACCOUNTUPDATE.ASP-Centralized .asp for Updating Member Accounts Based on Member-Intiated Updates of their Member Information

...

   sql = "UPDATE Members SET"

         if request.form("fname") <> "" then

            sql = sql & " Members.fname ='" & stripchars(request.form("fname")) & "',"

         end if

         if request.form("lname") <> "" then

            sql = sql & " Members.lname ='" & stripchars(request.form("lname")) & "',"

         end if

         sql = sql & " Members.pass ='" & stripchars(pass) & "',"

         sql = sql & " Members.address1 ='" & stripchars(address1) & "',"

         sql = sql & " Members.address2 ='" & stripchars(address2) & "',"

         sql = sql & " Members.city ='" & stripchars(city) & "',"

         sql = sql & " Members.stateid ='" & request.form("stateid") & "',"

         sql = sql & " Members.zip ='" & stripchars(zip) & "',"

         sql = sql & " Members.hmareacode ='" & stripchars(hmareacode) & "',"

         sql = sql & " Members.hmphone ='" & stripchars(hmphone) & "',"

         sql = sql & " Members.wkareacode ='" & stripchars(wkareacode) & "',"

         sql = sql & " Members.wkphone ='" & stripchars(wkphone) & "',"

         sql = sql & " Members.publicphone =" & request.form("publicphone") & ","

         if request.form("email") <> "" then

            sql = sql & " Members.email ='" & stripchars(request.form("email")) & "',"

         end if

         sql = sql & " Members.publicemail =" & request.form("publicemail") & ","

         sql = sql & " Members.maiden ='" & stripchars(maiden) & "',"

         sql = sql & " Members.ESelect =" & request.form("eselect") & ","

         sql = sql & " Members.Eaccept =" & request.form("eaccept") & ","

         sql = sql & " Members.EGenie =" & request.form("egenie") & ","

         sql = sql & " Members.EGen =" & request.form("egen") & ","

         sql = sql & " Members.download = 1,"

         sql = sql & " Members.AdmModDate = #" & Date() & "#,"

         sql = sql & " Members.EOK =" & request.form("eok") & " "

         sql = sql & " WHERE Members.memberID=" & session("memberid") & ";"

         Set rs = Server.CreateObject("ADO.Recordset")

         rs.Open sql,Conn,3

End If

newpage = "profile.asp?memberid=" & session("memberid")

response.redirect newpage

%>

The process of managing account information follows the pages utilized for creating a New Account very closely. Although these pages can be fairly easily copied over and modified for use, I recommend that you leave these edit account pages until late in the development process because changes in the New Account pages and Member table have cascading impact on the Edit Account Pages. Most test users have little need to manage accounts and can easily live without this set of features until late in the development process.

Summing Up

Establishing a membership-based community relies upon effective management of the New Account process, logon and account validation, and effective distribution of account maintenance into the membership community. However, if the community sponsor intends to charge fees for products and services, providing a compelling and interactive user experience coupled with effective administration and a convenient billing/payment service will determine the overall effectiveness of the site as a business venture.

Appendix C, "Delivering an Interactive Introduction Service," explores delivering an interactive service, followed by a look at the administrative and payment services included the Introduction Service site.


© 1997, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.

Back Home page. page.

<Appendix A: "Case Study: Building an Interactive Product" / ASP Book Home Page / Appendix C: "Delivering an Interactive Introduction Service">




Last update: 30.10.99. Created by Konstantin Chapkanov.