Taking Care Of Pre_Init

The Page class exposes a Pre_Init event because the MasterPageFile and Theme properties need to be set early in the lifecycle of a web form. Pre_Init is the event to hook if you want to assign these properties dynamically in code. The natural question is how to implement master page and theme selection for all web forms in an application without adding a Pre_Init event handler to every single web form.

Brock Allen has one elegant solution, which is to use an HttpModule. Brock’s module hooks the PreRequestExecuteHandler and ultimately handles all the PreInit events with a single method in an HttpModule. I haven’t touch VB in a week, so here is what that solution would look like in VB:

Imports System.Web

Public Class MasterAndThemeModule
    
Implements IHttpModule

    
Public Sub Dispose() Implements IHttpModule.Dispose
    
End Sub

    Public Sub Init(ByVal context As System.Web.HttpApplication) _
            
Implements IHttpModule.Init

        
AddHandler context.PreRequestHandlerExecute, _
                  
AddressOf Application_PreRequestHandlerExecute
    
End Sub

    Public Sub Application_PreRequestHandlerExecute(ByVal sender As Object, _
                                                    
ByVal e As EventArgs)
        
Dim application As HttpApplication
        application =
DirectCast(sender, HttpApplication)

        
Dim page As Page
        page =
TryCast(application.Context.CurrentHandler, Page)

        
If Not page Is Nothing Then

            AddHandler page.PreInit, _
                    
AddressOf Page_PreInit
        
End If
    End Sub

    Public Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)

        
Dim page As Page
        page =
DirectCast(sender, Page)
        page.MasterPageFile =
"code to select master page"

    End Sub

End
Class

You could drop the above code into an App_Code file and configure the module in web.config like so:

<httpModules>
   <
add name="MasterAndThemeSelection" type="MasterAndThemeModule"/>
</
httpModules>

Of course, the beauty of an HttpModule is that you could put the code into a class library and configure the module to run in a number of applications.

The alternative is to use inheritance, which requires a base class derived from the Page class. s

Imports System.Web.UI

Public Class BasePage
    
Inherits Page

    
Public Sub Page_PreInit(ByVal sender As Object, _
                            
ByVal e As EventArgs) Handles Me.PreInit
        
Me.MasterPageFile = "code to select master page file"
    End Sub
End
Class

Any web form that wants to take advantage of the common PreInit event handler will need to inherit from the BasePage class either by changing the Inherits attribute in the @ Page directive (for forms with no CodeFile) or by changing the Inherits line in the CodeFile. Inheritance can be slightly more intrusive, but it’s also easier to opt out of the behavior by not deriving from the BasePage.

Print | posted @ Saturday, December 10, 2005 3:31 AM

Comments on this entry:

Gravatar # re: Taking Care Of Pre_Init
by Thomas Eyde at 12/10/2005 4:33 AM

Thanks for the info. It's not you I am bugging, but I have this question:

Is it possible to package the master page file as a class? We don't really want to pass that look and feel *file* around, do we?

I was really hoping I could compile the master into the assembly and then reuse it in other projects. Seems like I have to wait for that one.
  
Gravatar # re: Taking Care Of Pre_Init
by scott at 12/10/2005 5:11 AM

Thomas - I think there are ways to compile pieces (master pages, user controls) and then reuse them. I have not tried it with the RTM bits so I'll need to do a few experiments...
  
Gravatar # re: Taking Care Of Pre_Init
by stan at 2/25/2006 1:56 AM

I tried to put this in global.asax file like Brock, but got error

'Page' is not a member of 'System.EventArgs'.

Do I put this is Generic Handler or in VB.Class file?

What might I be going wrong?


Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)
Dim t As String = HttpContext.Current.Profile.GetPropertyValue("Theme")
If t <> "" And t.Length > 0 Then
e.Page.Theme = t
Else
e.page.Theme = "ulaanBlue"
End If

End Sub
  
Gravatar # re: Taking Care Of Pre_Init
by anabhra at 8/22/2006 10:01 PM

Any futher info on sharing the master pages across applications (in the same domain)?
  
Gravatar # re: Taking Care Of Pre_Init
by scott at 8/23/2006 1:45 PM

anabhra, take a look at: odetocode.com/.../5469.aspx
  
Gravatar # re: Taking Care Of Pre_Init
by Ezequiel Jadib at 10/27/2006 1:37 PM

I use the httpModule, but i have this error

Content controls have to be top-level controls in a content page or a nested master page that references a master page

how can i do?
  
Gravatar # re: Taking Care Of Pre_Init
by scott at 10/29/2006 8:36 PM

@ Ezequiel: You must be setting the MasterPageFile for an .aspx page that does not use master pages. To set the MasterPageFile property on an .aspx means it can only have <asp:Content> controls inside.
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 3 and 5 and type the answer here: