I have recently been trying to develop an “HttpHandler” that will change the “Master Page” for the portal and sites on the fly based on various parameters. I am hoping that I will be able to validate the user and the zone they are coming from and display different master pages accordingly. My first idea was to create a new class library and override the “PageBaseType” within the “Web.Config”. This would have worked except that any pages that already have “Inherits” statements don’t work. This solution would involve having to change the “inherits” for each and every page in the site, something I am not about to do. My next approach was to create an “HttpHandler” that simply would override the “Page_PreInit” method and change the master page. I read various articles to work out what the code would be and also the best approach to doing this.
http://ryanfarley.com/blog/archive/2004/06/16/788.aspx
http://weblogs.asp.net/soever/archive/2006/11/14/SharePoint-2007_3A00_-using-the-masterpage-from-your-site-in-custom-_5F00_layouts-pages.aspx
http://www.lnbogen.com/OverrideOnPreInitOnAPageWithMasterPage.aspx
http://msdn.microsoft.com/msdnmag/issues/04/06/ASPNET20MasterPages
http://staff.develop.com/ballen/blog/PermaLink.aspx?guid=09befce7-f48e-4555-891c-13818fd75a56
http://odetocode.com/Articles/450.aspx
http://www.sharepointblogs.com/dwise/archive/2007/01/08/SingleMasterPage.aspx
After reading the articles above I decided to structure the code as follows:
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication httpApp = sender as HttpApplication;
if (httpApp != null)
{
Page page = httpApp.Context.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(page_PreInit);
}
}
}
void page_PreInit(object sender, EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
if (page.MasterPageFile.Contains("application.master"))
{
page.MasterPageFile = "~/_layouts/CustomApp.master";
}
else
{
page.MasterPageFile = "/_catalogs/masterpage/Custom.master";
}
}
}
public void Dispose()
{
}
This code simply hooked into the “PreInit” method of the page and changed the master page. If it was a page that was rendered from the “_layouts” directory it rendered using a different page. If it was a normal page it should render using my Custom.Master page. So now I had my code, so time to test. To test it I took the following steps:
1. Copy DLL to GAC
2. Add following lines to “Web.Config” for Web Application
<add name ="CustomHttpModule" type="HttpModule080507.CustomHttpModule, HttpModule080507, Version=1.0.0.0, Culture=neutral, PublicKeyToken=13494ee1574dcc83" />
3. IISRESET
4. Launch Portal Home page in Browser
5. Attach Visual Studio to w3wp.exe process for the portal and then step through the code
I added break points to the following lines of code:
1. context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
2. page.PreInit += new EventHandler(page_PreInit);
3. if (page.MasterPageFile.Contains("application.master"))
4. page.MasterPageFile = "~/_layouts/application1.master";
5. page.MasterPageFile = "/_catalogs/masterpage/BlueBand.master";
After some initial testing I noticed some very perculiar behaviour. I undertook the following tests.
1. Launch the portal main page
I expected the master page to change to my Custom.master. It did not
2. Press Site Actions, Site Settings then Modify All Site Settings
I expected the master page to change to my CustomApp.master page. It did
3. Select “Document Center” from top navigation
I expected the master page to change to my CustomApp.master page. It did
4. Select “News”, “Reports”, “Search”, “Sites” from the top navigation
I expected the master page to change to my Custom.master page. They did not
5. Created new Team Site and accessed this
I expected the master page to change to my Custom.master page. It did
As you can see I got very different results depending on where I was trying to access within the MOSS2007 platform. The pages that did not render the new master page didn’t seem to call my “page_PreInit” method at all. The debug window did show it hit the line to add the override method but that was it.

When I ran the test on the pages that did work the following took place.



As of yet I have not found a solution. I am still working on resolving this and once I have will continue with the rest of the code. If anyone has any ideas on this it would be much appreciated. I don’t profess to be a hard core developer so could use some guidance.