Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

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.

This entry was posted in .Net Development, Patterns and Practices. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

9 Responses to Expanding on ASP.NET BasePages from Eric Wise

  1. J. Doe says:

    I am getting an object reference error:

    UserInstance.ClientName = “Raymond Lewallen”;

    Any thoughts? Its static so im not sure why.

  2. Wil Welsh says:

    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.

  3. Tom,

    The “if” statement looks correct to me. When I did this last year, I copied and pasted that right out of working code.

  4. Tom says:

    is it just me or is the “if” statement within the Instance function of the ApplicationSessionManager incorrect?

  5. 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

  6. 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.

  7. ben says:

    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.

  8. 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.

  9. 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…

Leave a Reply