[I hope that I don't drive my readers crazy. I'd love to settle on 1 topic and become an expert in that oen topic. I just have way too many interests right now]
As I have coded web apps (in both ASP and ASP.Net as well as JSP) over the last 6 or 7 years (wow, it's been that long), I have had a recurring problem. How do I transfer data between pages?
Initially my answer was what a lot of us do. I simply put the data in the QueryString. It's very easy and you can easily retrieve it. The only problem of course (that I discovered through someone else's err) is that power users quickly realize that by messing with values in the querystring they can get the page to potentially do different things (especially if you've forgotten to add necessary checks). This post here on The Daily WTF. Needless to say be cautious of QueryStrings and if you can avoid them then definitely avoid them.
After realizing what kinds of problems can happen I chose a different route. I build a small form with nothing but hidden fields and I post the form to the new page (usually through a javascript). The values are hidden in the form, so this seems like a good solution, but hold on... This is a good solution but it is definitely not a secure one. Form posts can be spoofed (it's never happened to me, but I've become aware of the fact that form posts have issues.
So now what can we do? I've heard people mention session. But cluttering session just sounds like a bad idea to me.
The answer that I have come up with is the app cache. It's perfect. Data never touches the client's machine. The only piece of information that the client touches is the the session id (which I combine with a “ket“ to create the cache's key). Cache can be set to timeout, so you're not waiting until session times out -- you can safely time out the information sooner because it is only for a page transfer. The only place this wouldn't work is if you're in a multi-server environment and you're not using sticky sessions.
Anyway, here's the code I wrote for this (it handles the adding of the Session ID to yor keys) [edited the code because Dave --a different one than the one I normally write about-- pointed out that I forgot the type on the first constant which is absolutely necessary]:
' Timeout for data being transfered is 2 minutes
Protected Const PAGE_XFER_CACHE_TIMEOUT_IN_MINUTES As Integer = 2
' Remove a key from the transfer cache
Public Function removeKeyFromContext(ByVal key As String) As String
context.Cache.Remove(key + Session.SessionID)
End Function
' Check if a particular key exists in the transfer cache
Public Function existsInContext(ByVal key As String) As Boolean
Return (Not (context.Cache(key + Session.SessionID) Is Nothing) AndAlso _
Len(CStr(context.Cache(key + Session.SessionID))) > 0)
End Function
' Reads a key back from the transfer cache
Public Function readFromContext(ByVal key As String) As String
Dim __InContext As Boolean = existsInContext(key)
If __InContext = False Then Return ""
' [ As my mom says “Some days I do better than others.. some more bad code,
' but I think this is the last of it]
'If __InContext Then
' Context.Items.Add(key, _
' Server.UrlEncode(CStr(context.Cache(key + Session.SessionID).ToString)))
'End If
Return Server.UrlDecode(Context.Cache(key + Session.SessionID).ToString)
End Function
' Writes data with a key to the Transfer Cache
Public Sub writeVarToContext(ByVal key As String, ByVal value As Object)
If existsInContext(key) Then removeKeyFromContext(key) ' [fixed this line of code]
context.Cache.Add(key + Session.SessionID, _
value, Nothing, Date.MaxValue, _
System.TimeSpan.FromMinutes(PAGE_XFER_CACHE_TIMEOUT_IN_MINUTES), _
CacheItemPriority.Default, Nothing)
End Sub
There you go. Let me know what you guys think.
Print | posted on Saturday, July 24, 2004 4:14 PM