As you all ready know SharePoint facilitates custom branding through master pages. it is very easy for you to change the look and feel of a site just by changing the site master page and system master page. but, unfortunately if you are in position where you have to apply custom master page to an out-of-the-box application page, such as _layouts/Upload.aspx, _layouts/CreatePage.aspx or a any other custom application page you are in a bit of a difficult situation. simply, because SharePoint user interface does not provide this functionality. SharePoint simply apply Application.master to all of the application pages. one way of by passing this problem is that changing the Application.master which is not recommended at all. simply because, this may get overridden during system upgrades and in the other hand you don't have a control over which application pages you want to be attached with custom master page.
So, how do we apply custom branding to application pages? one simple solution is to intercept page requests that are generated from application pages and change master page property before the page is rendered. this is where System.Web.IHttpModule comes in to play.
First of all, I implement IHttpModule interface and implement two interface methods Init() and Dispose() as follows;
private String pagesToBeProcessed = "_layouts/Upload.aspx,_layouts/CreatePage.aspx";
private String masterPageName = "mycustom.master";
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(Context_PreRequestHandlerExecute);
//get pages to be processes
if (!String.IsNullOrEmpty(ConfigurationSettings.AppSettings["Application.Pages"]))
{
pagesToBeProcessed = ConfigurationSettings.AppSettings["Application.Pages"].ToString();
}
//get master page
if (!String.IsNullOrEmpty(ConfigurationSettings.AppSettings["Application.MasterPage"]))
{
masterPageName = ConfigurationSettings.AppSettings["Application.MasterPage"].ToString();
}
}
public void Dispose()
{
}
After this, we have to implement Context_PreRequestHandlerExecute and Page_PreInit methods as follows;
void Context_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(Page_PreInit);
}
}
void Page_PreInit(object sender, EventArgs e)
{
try
{
Page page = sender as Page;
ChangeMasterPage(page);
}
catch (Exception ex)
{
//Handle Exception
}
}
This where all the processing is happening. in the method, the page request is intercepted and if the page is from the list of pages that needs to be attached with custom master page then replace the master page url of the page to the custom master page.
private void ChangeMasterPage(Page page)
{
if (page != null)
{
String[] tokens = page.Request.Url.GetLeftPart(UriPartial.Path).ToString().Split('/');
/* get hold of the page name of the request */
String pageName = tokens[tokens.Length - 1];
if (pagesToBeProcessed.Contains("_layouts/"+pageName))
{
// Is there a master page defined?
if (page.MasterPageFile != null)
{
// only replace the application.master file
if (page.MasterPageFile.Contains("application.master"))
{
try
{
String url = "~" + SPContext.Current.Site.ServerRelativeUrl + "/_catalogs/masterpage/" + masterPageName;
page.MasterPageFile = url;
}
catch(Exception ex)
{
//don't do any thing
}
}
}
}
}
}
Finally, sign, build the project and drop the assembly file to GAC. after placing the assembly in the GAC do an iisreset.
Now, we have a IHttpModule that can trap page requests and change master page reference. next, this module has to be registered in web.config.
Register the code module as safe control by adding a <SafeControl> entry under <SafeControls>.
Register the IHttpModule as follows;
<httpModules>
.
.
.
.
<add name="MasterPageHttpModule" type="[assembly name], [namespace], Version=[version number], Culture=neutral, PublicKeyToken=[public key token]" />
<httpModules>
replace assembly name, namespace and public key token accordingly.
as the very last step, you may add two AppSettings values in to web.config that defines the custom master page name and the page names that need to be attached with custom master page. by default the module will change the master page urls of _layouts/Upload.aspx, _layouts/CreatePage.aspx.
After implementing the module, next time your application pages will be rendered with your custom master page.
No comments:
Post a Comment