Introduction
In this article, I am going to explain how to merge BasePage classes with MasterPage so that you can control UIs and page functionalities.
MasterPage
MasterPage is a new technique in ASP.NET 2.0 that is very helpful in maintaining full web application design in generic places. Using this, we can change the complete look and feel of the application within a short duration. Normally, we keep our layout designs in MasterPage and all other pages will extend the UI from it.
Click here to see more about MasterPages.
Is it Inheritance?
Even though we are extending the UI from MasterPage, it's not an inheritance concept. MasterPage is just providing the content place-holder to enable the extended page to provide the page-specific UI.
Creating a Simple Example
Step 1
Create a MasterPage with some header content, footer content and place holder content, as below.
MasterPage.Master
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>Header Contents</h3><hr />
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
<hr /><h3>Footer Contents</h3>
</div>
</form>
</body>
</html>
Step 2
Create a WebPage and refer the MasterPage using the page directive, as below.
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"
MasterPageFile="~/MasterPage.master"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content runat="server" ContentPlaceHolderID="ContentPlaceHolder1"
ID="PageContent">
<b>Content</b>
</asp:Content>
Step 3
Run the sample. You can see the following output with header, footer and page-specific content. This is how we are placing generic UI content (header, footer) into a generic place.
Output: Default.aspx (Rendered using "MasterPage")
Disadvantages of MasterPage
MasterPage is just for the UI extension. You cannot achieve actual inheritance advantages using that. For example, using inheritance you can have generic methods and properties in the base class that can be used by all the derived web forms, i.e. you can have logging, exception handling, session handling in base class and these can be used by all the web forms.
BasePage
What is BasePage?
BasePage is just a concept that was followed by many developers before ASP.NET 2.0. It has also been called by different names like "PageBase," "WebPageBase" and many more. The concept of BasePage is really simple: to create a class that is inherited from System.Web.UI.Page
and use this class as a base class for all the web forms. Unfortunately, you will not get all the UI from the base class to a derived class in web form. This is because, in ASP.NET, the UI is built using the Context approach. The inheritance will not help to render the base class UI, even though you can get the BasePage UI by adding some code in RenderChild
or in the Render
method of the base class.
Creating a Simple Example
Step 1
Create two user controls (*.ascx) for the header and footer, as below.
HeaderControl.ascx
<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="HeaderControl.ascx.cs" Inherits="HeaderControl" %>
<h3>Header Content</h3><hr />
FooterControl.ascx
<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="FooterControl.ascx.cs" Inherits="FooterControl" %>
<hr /><h3>Footer Content</h3>
Step 2
Just create a class and inherit it from System.Web.UI.Page
. Then add some generic methods like Logging
, Session
, etc. Override the Render
method and add the code like below.
BasePage.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
public class BasePage:System.Web.UI.Page
{
public BasePage()
{
_Logger = new Logger();
}
protected override void Render(HtmlTextWriter writer)
{
Control header = this.LoadControl("HeaderControl.ascx");
Control footer = this.LoadControl("FooterControl.ascx");
this.Form.Controls.AddAt(0, header);
this.Form.Controls.AddAt(this.Form.Controls.Count, footer);
base.Render(writer);
}
private Logger _Logger;
public Logger Logger
{
get { return _Logger; }
}
private SessionData _CurrentSession;
public SessionData CurrentSession
{
get { return _CurrentSession; }
set { _CurrentSession = value; }
}
}
Logger Class
public class Logger
{
public void LogWarning(object Message)
{
}
public void LogError(object Message)
{
}
public void LogTrace(object Message)
{
}
}
Session Handling Class
public class SessionData
{
public int UserId
{
get
{
return int.Parse(
HttpContext.Current.Session["UserId"].ToString());
}
set { HttpContext.Current.Session["UserId"] = value; }
}
public List<int> ItemIds
{
get { return (List<int>)HttpContext.Current.Session["Items"]; }
set { HttpContext.Current.Session["Items"] = value; }
}
}
Note: the above session handling and logger classes are just added for explanatory purposes. You can also add any generic elements with respect to your project.
Step 3
Create a web form and change the base class name from System.Web.UI.Page
to BasePage
.
Default2.aspx.cs:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class Default2 : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
Result
Now we are able to render the UI from the base class, as with MasterPage. We are also using methods and properties provided by the base class. So really, we can control our UI and the functionalities of the application from a single place.
Output: Default2.aspx (Rendered using "BasePage")
Disadvantages of BasePage
This is not really a proven technique, but still, I've already implemented it in many client places and it's really working well, even for huge requests. Also, we are adding the controls only inside the <form>
tag, so updating <head>
tag elements like style sheet references and page titles is a bit difficult.
Merging BasePage and MasterPage
It's easy to merge these two techniques, BasePage and MasterPage. Just add the following code to the BasePage constructor and remove the code that we added in the Render
method, so now the BasePage will look like below.
Changing BasePage.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
public class BasePage:System.Web.UI.Page
{
public BasePage()
{
_Logger = new Logger();
this.MasterPageFile = "MasterPage.Master";
}
private Logger _Logger;
public Logger Logger
{
get { return _Logger; }
}
private SessionData _CurrentSession;
public SessionData CurrentSession
{
get { return _CurrentSession; }
set { _CurrentSession = value; }
}
}
Try to access the generic methods that are provided by BasePage from the derived web page.
Intellisense of the Default2.aspx.cs File, which is Inherited from BasePage
In a single place -- I would like to call it MasterBasePage
-- we can control the following things of the web application:
- UI layout [from MasterPage]
- Session handling [from BasePage]
- Project-specific properties [from BasePage]
- Logging [from BasePage]
- And so on�
Issues in Visual Studio 2005
Here we are not using MasterPage page directive attributes in derived pages, so Visual Studio 2005 is giving some error in the designer to use the content place holder. Right now, I'm looking into this issue.
History
- 14 November, 2007 -- Original version posted