Raymond Lewallen

Sponsors

The Lounge

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Expanding on ASP.NET BasePages from Eric Wise
Eric Wise wrote a post on BasePages and inheritance in Asp.Net. Great post, and you should read it before reading this one, as this is an expansion of what he started.

I made a comment about how I do the same thing but also include a way to access the session. First lets take a look at the code Eric provided, with a few additions that supply access to a custom session manager:

using System;

public class BasePage : System.Web.UI.Page
    {
        public ApplicationSessionManager UserInstance;

        private string _connectstring = "";
        protected string connectstring
        {
            get
            {
                if(_connectstring == "")
                {
                    //Get Connection string

                }
                return _connectstring;
            }
        }
  
        public BasePage() : base()
        {
            base.Init += new System.EventHandler(PreInit);
        }

        protected void PreInit(object sender, System.EventArgs e)
        {
            UserInstance = ApplicationSessionManager.Instance;
        }
    }


Now lets look at the singleton ApplicationSessionManager class that goes with it. I do this primarily so that the use of the session object doesn't get out of control. I recently did a code review on an Asp.Net project that had over 45 distinct session variables. What a nightmare to maintain and keep track of! This happened because there was not solid implementation like below to define what the session should be and what should exist in it. Also, this ApplicationSessionManager class provides a strongly-typed way to access session information, as you can see below. No more (int)Session["MyInteger"] occurs, which saves quite a bit because you don't have to be knowledgable of the object type stored in session. Using the singleton below provides you that strongly-typed interface. Now lets take a look at it:

using System;
using System.Web;

    [Serializable()]
    public class ApplicationSessionManager
    {
        private ApplicationSessionManager()
        {
        }

        public static ApplicationSessionManager Instance 
        {
            get 
            {
                HttpContext context = HttpContext.Current;
                ApplicationSessionManager theSession;
                if (!(context.Session["TheSession"] == null && (context.Session["TheSession"] is ApplicationSessionManager))) 
                {
                    theSession = ((ApplicationSessionManager)(context.Session["TheSession"]));
                } 
                else 
                {
                    theSession = new ApplicationSessionManager();
                    context.Session["TheSession"] = theSession;
                }
                return theSession;
            }
        }

        public void Abandon()
        {
            HttpContext.Current.Session.Abandon();
        }

        public void Clear()
        {
            HttpContext.Current.Session.Clear();
        }

        private string clientName;
        public string ClientName 
        {
            get 
            {
                return clientName;
            }
            set 
            {
                if (value == null) 
                {
                    throw new ArgumentNullException("ClientName", "Cannot store a null value in session.");
                }
                clientName = value;
            }
        }
    }


As you can see, all you need to do is add a property for each item you want to store in session, and really the only thing stored in session is the ApplicationSessionManager class itself, in this case, under the name "TheSession". This is a very common way to approach this scenario and has been in use since the release of .Net.

And finally, a WebForm1.aspx.vb to go along with it

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace BaseWebProject
{
    /// <summary>

    /// Summary description for WebForm1.
    /// </summary>
    public class WebForm1 : BasePage
    {
        private void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here

            UserInstance.ClientName = "Raymond Lewallen";
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //

            InitializeComponent();
            base.OnInit(e);
        }
        
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>

        private void InitializeComponent()
        {    
            this.Load += new System.EventHandler(this.Page_Load);
        }
        #endregion
    }
}


Probably not much need for me to elaborate on what is going on here, as it is pretty striaght-forward. This type of scenario works extremely well for expanding out and adding core functionallity for all your pages. Again, see Eric's post for some elaboration on the BasePage inheritance technique.

Posted 02-02-2005 3:25 PM by Raymond Lewallen

[Advertisement]

Comments

Brendan Tompkins wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 02-02-2005 4:05 PM
Raymond,

I agree that a strongly typed wrapper around the session object is the way to go. I blogged about this a while back, and use something similar to this at work:

http://codebetter.com/blogs/brendan.tompkins/archive/2004/01/21/5856.aspx

What I like about your model, is that you don't have to instance your state obejct, it just lives as part of the page class. What I don't like is that you end up with a very large object, with slots for every possible session obejct, which doesn't scale well either.

The state object I've created also allows you to store your State in different places (ViewState, Application, Cache) ... Perhaps I'll blog about this tomorrow, when I have more time.

Wonder if we could put our heads together, and get the best of both worlds somehow...
Raymond Lewallen wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 02-02-2005 4:57 PM
Brendan,

The small community of Codebetter.com is already paying off very well. A post by Eric not 6 hours ago has gotten him, Salik, me and you all involved and discussing base page inheritence and what goes along with it, without having to wade through 150 other posts. We've since discovered that we each build different implementations of session wrappers (expected, of course), both with their good and bad behaviors.

The thing you mentioned about mine is the same thing I don't like about your model: the instance. I do really like the implementation of the multiple places to store State information. I've been brainstorming lately about a way to re-implement a caching pattern into the BasePage scenario, based on our application requirements. I fully agree that perhaps we can each take the models we have and put them together somehow to come up with a more solidified solution to the scenarios.

I do agree that you can end up with very large objects with my model, depending on the application. I can't elaborate on the project I work on due to the nature of the project and client, but the model works out well if you were to be aware of our circumstances and requirements. In the meantime, we can work on combining our models and perhaps the models of some others who can comment to come up with a really great pattern for all scenarios for storing State information.
ben wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 02-02-2005 7:24 PM
We use the same concept as you published here, and we also put some security logic into the base page's OnLoad method, it gives you the benefit of security and its completely transparent to the developer writing the pages.
Raymond Lewallen wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 02-03-2005 6:52 AM
Ben,

Yes, we also have a security model in our BasePage, but covering everything you can implement into a BasePage for web forms would take dozens of posts, so I only covered a session wrapper here. In the near future I'll talk about a security model that can be implemented into the BasePage as well.
Brendan Tompkins wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 02-03-2005 8:27 AM
Raymond,

Yeah! Have all of these coders reading these new blogs is amazing! I'm having fun.

I'm going to do a new post, because I have a lot more to say about this...

B
TrackBack wrote StateClassBase Redux
on 02-03-2005 9:24 AM
TrackBack wrote Master pages NOW!
on 02-04-2005 4:38 PM
TrackBack wrote How do you like CodeBetter.com so far?
on 02-14-2005 5:56 PM
TrackBack wrote A Better ASP.NET State Pattern
on 02-23-2005 12:13 PM
TrackBack wrote re: ASP.NET Page Inheritance - Base Page Classes in your Web Applications
on 03-14-2005 1:26 PM
Tom wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 03-13-2006 8:03 PM
is it just me or is the "if" statement within the Instance function of the ApplicationSessionManager incorrect?
Raymond Lewallen wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 03-13-2006 8:07 PM
Tom,

The "if" statement looks correct to me. When I did this last year, I copied and pasted that right out of working code.
Wil Welsh wrote re: Expanding on ASP.NET BasePages from Eric Wise
on 04-30-2006 8:50 PM
The left half of the if statement is missing a closing ")"  If you copy & paste as it is on the web page here, it will give a null reference exception everytime you try and get an instance.  It does this because everytime it will evaluate to true & return you null from the session.  It will never evalutate to false & create a new session.

I did some rewriting on the basepage class here, its a little cleaner because resharper comes up complaining about hiding the preinit via inheritance and demanding a "new" qualifier on it every time you open the file up.

public class BasePageRoot : System.Web.UI.Page
   {
       public ApplicationSessionManager UserInstance;

       public BasePageRoot() : base()
       {
           this.PreInit += new EventHandler(BasePageRoot_PreInit);
       }

       void BasePageRoot_PreInit(object sender, EventArgs e)
       {
           //MasterPageFile = "~/PaidCustomer.master";
           UserInstance =  ApplicationSessionManager.Instance;
       }
   }

Don't mind the root business... I have a heirarchy of basepages that inherit from each other, like

JSfirm.Basepages.JobSeeker.Open
JSfirm.Basepages.JobSeeker.Secure
JSfirm.Basepages.Employer.Open
JSfirm.Basepages.Employer.Secure

which all inherit from the baseroot.
Giddy Up! - Erik Lane's Blog wrote TulsaTechfest Summary from me, Erik Lane
on 10-16-2006 12:18 AM
Giddy Up! - Erik Lane's Blog wrote TulsaTechfest Summary from me, Erik Lane
on 10-16-2006 12:19 AM
jsfirm wrote jsfirm
on 04-06-2008 5:57 PM

Pingback from  jsfirm

Mesothelioma Law professional practising in Raymond, New Hampshire wrote Mesothelioma Law professional practising in Raymond, New Hampshire
on 01-14-2009 2:49 AM

Pingback from  Mesothelioma Law professional practising in Raymond, New Hampshire

Add a Comment

(required)  
(optional)
(required)  
Remember Me?