views:

551

answers:

2

I have the following BasePage class...

Public Class BasePage
    Inherits System.Web.UI.Page

    Private litError As Literal
    Protected SO As Session

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SO = Session.Item("SO")

        If SO Is Nothing Then
            Session.Abandon()
            Response.Redirect("~/timeout.htm")
        End If

        litError = Page.FindControl("litError")
        If litError IsNot Nothing Then
            litError.Visible = False
        End If
    End Sub

    Protected Sub ShowMessage(ByVal Message As String)
        Show(Message, "message")
    End Sub

    Protected Sub ShowError(ByVal Message As String)
        Show(Message, "error message")
    End Sub

    Protected Sub ShowSuccess(ByVal Message As String)
        Show(Message, "success message")
    End Sub

    Private Sub Show(ByVal Message As String, ByVal CssClass As String)
        If litError IsNot Nothing Then
            litError.Text = String.Format("<span class=""{0}"">{1}</span>", CssClass, HttpUtility.HtmlEncode(Message))
            litError.Visible = True
        End If
    End Sub
End Class

Every page in this application inherits this class. The SO variable represents a custom session class, that is very simple and just holds a couple of basic settings to be used throughout the application. The problem is, my Page_Load in this base class does not fire if a natural postback occurs (in this case, it is a gridview postback by sorting/paging). Then later in my code when I reference SO, I get a null reference exception because it hasn't been pulled from session.

Why doesn't the base Page_Load fire?

+1  A: 

Try moving your code into the Page_Init event.

Microsoft has some info on each event in the lifecycle http://msdn.microsoft.com/en-us/library/ms178472.aspx. This MSDN page tells you what types of things you should handle in each event.

You might want to think about implementing SO as a property, where the Get does (not sure if this is correct VB...)

    Dim so As Session = Session.Item("SO")
    If so Is Nothing Then
        Session.Abandon()
        Response.Redirect("~/timeout.htm")
    End If
    return so
s_hewitt
A: 

It could be that something else is happening in the Init events that is causing it to fail. So rather than it not being called it just hasn't been called yet.

It could be that the autoevent wireup isn't wiring it up correctly, tend to override the OnInit event and attach the events manually myself, I have also read somewhere that this improves perfomance by not requiring the framework to do heaps of reflection on every post.

But back to your problem... try making the SO object private and create a property accessor for it that first checks that if the private is set, if not set it, before returning the private variable. If it isn't set and can't be found then it can abort the same way you are doing in the Load. This means that to load the variable you won't be dependent on the Page_Load from firing and thus the SO object should be available for you during the init routines, if you need it.

David McEwing