by Peter Wone - Wombat & Me
The trouble with Session.Contents
The Session.Contents collection is great, but there are certain limitations -
It is true that IIS applications can store global values in the Application.Contents collection, but these need to be initialised, so either you rather wastefully initialise everything an application could possibly want, or you find an alternative.
The question is how can we implement persistent named values, so the answer is a database. sscookies.inc is designed to be included near the start of your ASP file. It declares rsCookies and creates an updateable recordset in which it keeps named values. It lets you get or set named values. If you set the value of an item that doesn't exist, it is created, otherwise the value is updated. This code declares all of its variables, so it won't break under the influence of Option Explicit.
setCookieValue cookieName, fieldName,
|Application.Contents("DB")||A connection object accessing a database containing a
Cookie data is stored in a database table structured as shown at right.
Even though the
|getUserID()||A function that you must provide that returns something uniquely identifying the user. Values are local to individual users, except for those marked as Global.|
<% dim rsCookie, temp set rsCookie = createObject("ADODB.recordSet") rsCookie.cursorType = adOpenKeyset rsCookie.lockType = adLockOptimistic temp = "select * from Cookies where Global " + _ "or (userID=" & getUserID() & ")" rsCookie.open temp, Application("DB"), , , adCmdText function getCookieValue(cookieName, fieldName) dim temp temp = _ "(Cookie='" & cookieName & "') and " + _ "(fieldName='" & fieldName & "')" rsCookie.Filter = temp getCookieValue = "" getCookieValue = rsCookie.fields("fieldValue") end function sub setCookieValue(cookieName, fieldName, value) dim temp temp = _ "(Cookie='" & cookieName & "') and " + _ "(fieldName='" & fieldName & "')" rsCookie.Filter = temp if (rsCookie.recordCount = 0) then rsCookie.addNew rsCookie.fields("userID") = getUserID() rsCookie.fields("Cookie") = cookieName rsCookie.fields("fieldName") = fieldName end if rsCookie.fields("fieldValue") = value rsCookie.update end sub %>
The easiest way to get a unique value is to interrogate Session.SessionID. Assign this value to the user by writing it into the response.Cookie. The following code will get it from Sessions when possible and failing that retrieve it from the cookie.
<% function getUserID() dim id on error resume next id = Session("userID") if ((id = "") or IsNull(Session("userID")) ) then id = request.cookies("userID") session("userID") = id end if getUserID = id end function %>
Apart from ensuring that the dependencies are satisfied, all you need do is include sscookies.inc near the start of your ASP code.
Then you can use the methods getCookieValue and setCookieValue.
You can achieve global constants by manually inserting values into the Cookies table and setting Global to true for the rows in question. Note that you can update the value of such a global constant. It would be possible to code against this but I didn't bother.