Monday, February 20, 2006

My Strongly Typed Session Wrapper for ASP.NET 2.0

Strongly Typed Session Wrapper in ASP.NET 2.0

Here's my Strongly typed session wrapper in .net 2.0. Its a singleton that interacts with the context object. Its adapted from c# code from Raymond Lewallen. I couldn't get his one to get the theSession = new ApplicationSessionManager(); context.Session["TheSession"] = theSession; line to work correctly after converting to vb.net.... It just kept coming back null. Probably something stupid I did.... So I wrote something of my own based off of his. Unfortunately I was too lazy to do type checking of the session object in the sessionmanager.vb.... That will probably be added later. (There is a case where you could save something to sesssion with the id "thesession" and overwrite this object with a string value without type checking it).

Be sure to add serializable to the class type... I included a complex sub-class for illustration purposes when it comes to instantiating this bad boy.

SessionManager.vb

Imports System.Web
Namespace JSfirm.Session
_
Public Class SessionManager
Private Const SESSION_MANAGER As String = "SESSION_MANAGER"
Private _Messageinfo As MessageInfo

Private Sub New()
_Messageinfo = New MessageInfo
End Sub

Public Shared ReadOnly Property Instance() As SessionManager
Get
Dim context As HttpContext = HttpContext.Current
Dim manager As SessionManager = CType(context.Session(SESSION_MANAGER), SessionManager)
If manager Is Nothing Then
manager = New SessionManager
context.Session(SESSION_MANAGER) = manager
End If
Return manager
End Get
End Property

Public Sub Abandon()
HttpContext.Current.Session.Abandon()
End Sub

Public Sub Clear()
HttpContext.Current.Session.Clear()
End Sub


#Region "Properties"
Private _clientName As String
Public Property ClientName() As String
Get
Return _clientName
End Get
Set(ByVal value As String)
If value Is Nothing Then
Throw New ArgumentNullException("ClientName", "Cannot store a null value in session.")
End If
_clientName = value
End Set
End Property


Public Property DisplayMessage() As MessageInfo
Get
Return _MessageInfo
End Get
Set(ByVal value As MessageInfo)
_MessageInfo = value
End Set
End Property



Public Class MessageInfo
Private _PageTitle As String
Public Property PageTitle() As String
Get
Return _PageTitle
End Get
Set(ByVal value As String)
_PageTitle = value
End Set
End Property


Private _Headline As String
Public Property Headline() As String
Get
Return _Headline
End Get
Set(ByVal value As String)
_Headline = value
End Set
End Property

Private _Message As String
Public Property Message() As String
Get
Return _Message
End Get
Set(ByVal value As String)
_Message = value
End Set
End Property

Private _RedirectURL As String
Public Property RedirectURL() As String
Get
Return _RedirectURL
End Get
Set(ByVal value As String)
_RedirectURL = value
End Set
End Property
End Class
#End Region

End Class

End Namespace

Here's my basepage to instantiate it.

basepage.vb

Imports Microsoft.VisualBasic

Namespace JSfirm.Basepages
Public MustInherit Class Root
Inherits System.Web.UI.Page

Public MySession As JSfirm.Session.SessionManager

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
MySession = JSfirm.Session.SessionManager.Instance
End Sub
End Class
End Namespace

Then in your Actual pages, you can add & extract data from session in a strongly typed manner as so.

MySession.ClientName = "Allanon of Paranor"

and extract them using the same object semantics. textbox1.text = MySession.ClientName

here is the link to the original c# project this was based off of.

Generic Message & Redirect Page Compat w Master Pages

I made a generic Message display page for the site. None of the examples online worked with the master pages functions of asp.net 2.0 since the master page has control of the <head> tags & there's no way to declare them from a child without a codebehind function. My goal was to make it so that I could call one method & pass in the messsages on the page via a parameter list.

In your master page, set the <head> tag to <head runat=server> Do not specify an ID= tag or else things will go all squigly on you in the codebehind.


Here's the source for the generic page. Its just a couple labels.


<%@ Page Language="VB" MasterPageFile="~/Common/Master/JobSeeker.master" AutoEventWireup="false" CodeFile="MessageDisplay.aspx.vb" Inherits="MessageDisplay" title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">


<asp:Label ID="lblHeadline" runat="server" Text="Label"></asp:Label><br />

<asp:Label ID="lblMessage" runat="server" Text="Label"></asp:Label><br />

<asp:HyperLink ID="hlRedirectLink" runat="server">HyperLink</asp:HyperLink>


</asp:Content>


Here's the Codebehind. It pulls values in from a strongly typed session variable, but you can adapt the code to pass them in with whatever parameter mechanism you prefer.


Partial Class MessageDisplay

Inherits JSfirm.Basepages.JobSeeker.Open


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


Me.Title = MySession.DisplayMessage.PageTitle


lblHeadline.Text = MySession.DisplayMessage.Headline

lblMessage.Text = MySession.DisplayMessage.Message


hlRedirectLink.Text = "<a href='" + MySession.DisplayMessage.RedirectURL + "'>Click here</a> to continue if your browser does not automatically direct you."


'Get the htmlHead your aspx page is using (from the Master page)

'/Master page must include the runat server attribute in the head tag: <head runat="server">

'Do not give an ID to the head...

Dim head As HtmlHead = CType(Header, System.Web.UI.HtmlControls.HtmlHead)


'Create a htmlMeta object

Dim meta As HtmlMeta = New HtmlMeta()


'Specify meta attributes

meta.HttpEquiv = "REFRESH"


Dim strContentString As String = "5;URL="

strContentString += MySession.DisplayMessage.RedirectURL

meta.Content = strContentString


'Add the meta object to the htmlhead's control collection

head.Controls.Add(meta)


End Sub

End Class


 


Now in your basepage (you know... the one you should inherit all pages in your project from instead of the system.web.ui.page....), insert this function or something similar. Note that the mysession business is just my strongly typed instance of a session object.


Public Function DisplayMessage(ByVal PageTitle As String, ByVal Headline As String, ByVal Body As String, ByVal redirecturl As String)

MySession.DisplayMessage.PageTitle = PageTitle

MySession.DisplayMessage.Headline = Headline

MySession.DisplayMessage.Message = Body

MySession.DisplayMessage.RedirectURL = redirecturl

Server.Transfer("/JobSeeker/MessageDisplay.aspx")

Return Nothing

End Function


Voila! Now in any page where you want to redirect you just have one line to call it all. Say for instance, you have a "delete user" button.... Instead of having a boring text... you can do this from your child pages.


DisplayMessage("Delete Message", "User Successfully Deleted!", "lorem ipsum dolar sit mieum paragraph", "/JobSeeker/Default.aspx")


And it will display a message to the user in a new page... but since it transfer's, the url stays the same until the redirect to "/jobseeker/default" occurs.


This is a pretty basic example.... The design could be expanded to have a few overloads for excluding text or redirect links, specifying redirec timeout etc...


This was loosely based off of http://www.west-wind.com/presentations/wwMessageDisplay/wwMessageDisplay.asp

as it appered in the Feb 2005 article in Code Magazine. However there are a few large differences between this & theirs. Their implementation does not support meta refresh in a master pages scenerio with a callback to the master page with the redirect url. It was authored before master pages. Theirs is in c#, and theirs has a bunch of coding garbage to help out with relative css links and a very awkward handling of the displaypage method in the template page. Its just a bunch of labels in mine. If you feel that you need to work with the context object to pass the values in, then more power to you... but in my case, i just added a class to my session like this & pass it around.


Public Class MessageInfo

Private _PageTitle As String

Public Property PageTitle() As String

Get

Return _PageTitle

End Get

Set(ByVal value As String)

_PageTitle = value

End Set

End Property


Private _Headline As String

Public Property Headline() As String

Get

Return _Headline

End Get

Set(ByVal value As String)

_Headline = value

End Set

End Property


Private _Message As String

Public Property Message() As String

Get

Return _Message

End Get

Set(ByVal value As String)

_Message = value

End Set

End Property


Private _RedirectURL As String

Public Property RedirectURL() As String

Get

Return _RedirectURL

End Get

Set(ByVal value As String)

_RedirectURL = value

End Set

End Property

End Class

Sunday, February 19, 2006

Welcome

Howdy there . I am Wil Welsh. I am an independent contractor working on ASP.NET web development out of Greensburg, PA, USA. I have about 2 years Experience in the .NET world and I am taking on my first real world project with the new ASP.NET 2.0 Framework, a site migration and ui redesign from classic asp. This journal will provide some sample code for architecture, links to technologies I find useful, and a whole general mish-mash of web development topics relating to ASP.NET 2.0 Development.