Introduction
When we hear �ASP.NET Page Templates�, we usually think of
it as a way to maintain design consistency on the website. But ideally, your
page template should do more for you. Why stop with just design consistency?
You should even try to get functional consistency out of it.
What is a Page Template?
When you have a team of ASP.NET developers building pages,
it would be ideal if design and functional consistency were maintained in all
of their pages. But, more often than not, this is not the case. At the end, you
would have a set of pages - all looking & behaving differently from each
other. This is where page templates come in � a page template is nothing but a
class that would be responsible for rendering the features common to all pages
like � header, logo, left/right menus, footers, help links, etc.
The Page Template class would inherit from System.Web.UI.Page
. The code
behind class for each page would then inherit from the Page Template class &
not System.Web.UI.Page
.
How do I create my page Template?
Create a class that inherits from System.Web.UI.Page
.
Override the Render
method �
protected override void Render(HtmlTextWriter writer)
{
writer.Write(@"<html>
<head></head>
<include html code for header, logo, left menu, tables
(up to the point where your aspx form is to be shown)>
");
base.Render(writer);
writer.Write(@"
</td>
<close all tables. Include html code for footers, etc>
</body></html>");
}
The above code is the simplest way to create a page
template.
Now, make sure all your aspx pages have their code-behind
inheriting from the class you have just created.
Also, be sure to
What else can I do with my Page Template?
We have seen how to ensure design consistency by using
Page Templates. Let�s go a bit further & try to do more with it.
We have to ensure that all ASP.NET developers, within a
team, code their pages such that minimum rework is required during integration.
This means that all pages have to be consistent in design & behavior.
Here are a list of behavioral features that would be
common to all pages within a site �
- Session
handling � Normally, you would have to explicitly set common
session variables like user ID, language, etc. Also, you would have to
repeatedly do session checks to see if a valid user has logged in.
- Internationalization
� All pages would require access to resource files to
handle the display of text in various languages. Also, you would have to
explicitly set the Culture objects for each page.
- Database
connectivity � All pages would interact with a class that
would handle database connections through ADO.NET. Or, your page itself
would open a connection to the database.
- Error
handling � All pages would behave in the same manner when
encountering an error � log the error, redirect to an error page &
display the appropriate error message.
- Use
of utility classes � All pages would interact with a set
of utility classes for mailing, logging, etc.
- Help
function � All pages would behave in the same manner when the
help button is clicked � open a help window, show help file. All help
files would be grouped together.
- Button
functionality � All pages would have a common set of
buttons. Some pages may have all buttons displayed & others may not.
For example � a site may have 3 buttons in all their pages (Continue,
Restart & Exit) except for their first & last page.
Now, it is possible for you to provide all these features
in your Page Template itself. You no longer have to worry about ASP.NET
developers in your team providing these very features inconsistently across
pages. Also, your developers would save time as they would not have to bother
about these features.
How do I do it?
Session handling features can be provided in your
Page Template by �
- Overriding
the
OnLoad
method in your Page Template class.
- In
the
OnLoad
method, do all session checks - e.g. check if user ID is available in the session.
- If
not, then redirect to an error page if the current page is not one of the
three
- The
first page of your site
- The
page responsible for setting session variables.
- The
Error page
Advantages
- Developers
need not write repetitive code like validating the user�s session,
redirecting incase of timeout/invalid user.
Internationalization features can be provided
in your Page Template by �
- In
the
OnLoad
method �
- Check
if the
ResourceManager
is in the Application object.
- If
not, create a new
ResourceManager
object pointing to your resource file
& store it in the Application object.
- Set
the
ResourceManager
object in a private variable.
- Also,
set the
CurrentCulture
and CurrentUICulture
objects based on the
language variable in the session.
- Provide
a protected method in your Page Template (say
GetResource
) that returns
the appropriate text (from the resource file) for the key passed to it.
This method uses the private ResourceManager
object set in OnLoad
.
Advantages
- Developers
do not have to repeatedly check the user�s language preference & then
set the Culture objects. This is done by the
OnLoad
method of the
template.
- A
single method is used to get data from resource files.
- The
resource files are set in the Page Template class itself & not by the
individual developer. This avoids any issues that may arise due to
incorrect resource file names across pages & developers.
Database connectivity & utility classes can be
provided in your Page Template by having them set as properties. They are then
accessible to your code-behind classes. Initialization of these properties can
be done in the OnLoad
. Alternatively, you can provide methods to initialize
them in your Page Template class. These methods can then be called from the
code-behind.
Advantages
- Ensures
that all developers in the team use features like connection strings,
utility classes, loggers, data access objects consistently.
- Initialization
of these utility classes can also be done in the template providing lesser
room for inconsistency.
- Since
all developers have to access the utility classes via the template, it
ensures that integration headaches are minimized.
- Ensures
that there can be no goof ups arising out of mismatches or incorrect
connection strings, log file names, email ids, etc
Error handling features can be provided in your
Page Template by �
- Including
an
ErrorCode
property in your PageTemplate
class.
- Add
a method
SetErrorCode(int code)
that sets the above property &
redirects to your error page. This method can be called from the
code-behind when an error/exception is encountered.
- Your
error page would then be able to retrieve the error code by
int errorCode = ((PageTemplate)Context.Handler).ErrorCode;
This error code can be used to
retrieve the appropriate error message from the resource file.
Advantages
- Ensures
that all developers in the team handle errors/exceptions consistently �
thereby saving time during integration.
- Ensures
that redirection to an error page, error logging, & error display
happen in exactly the same way across pages & developers.
Help features can be provided in your Page Template by �
- Including
a
HelpURL
property in your PageTemplate
class. This property is used in
the Render() method.
- This
property is set in the code-behind of your aspx.
Advantages
- Ensures
that developers in the team handle help features consistently � thereby
saving time during integration.
- No
hard coding of paths for help files is possible by the developer. The
paths have been hard coded in the template & as a result the developer
has to just provide the name of the help file.
- Setting
up help in the template avoids problems arising out of some developers
using absolute paths & others using relative paths to access the help
files.
Button functionality can be provided in your
Page Template by �
- Including
boolean
properties in your PageTemplate
class for each button. These
properties are used in the Render() method to show/hide the respective
button.
- This
property is set in the code-behind of your aspx.
Advantages
- Developers
need not bother about rendering of buttons on a page. Boolean properties
control the display of buttons. This is most useful in wizard style pages.
- Setting
up buttons & their functionality in the template avoids problems
arising out of some developers using absolute paths & others using
relative paths.
You can also add more features to the template based on
the needs of your site.
The sample ASP.NET application provided is an example of
the page template being put to use. The page template class is PageTemplate.cs.
All code-behind classes inherit from it. The example includes a form (FirstPage.aspx) that submits to a details page
(SecondPage.aspx). Also
provided are a search page (searcher.aspx) & an error page (Error.aspx).
Take a look at each of these pages & note how almost no code (per aspx) is required to provide session checks, i18n setup, DB & utility class setups, error handling, etc. Yet, every page behaves in exactly the same manner & at all times ! All the code providing the above listed features are in PageTemplate.cs.
If you were using a normal page template then every developer would have to include the same code in every page - to provide all the features listed above. We all know how painful that can be !
Sample Usage
Here's a quick guide on how to use this template in a new project -
- Create a new C# ASP.NET Web Application. Name it TestTemplate.
- Copy PageTemplate.cs, Error.aspx & Error.aspx.cs into the TestTemplate directory. Open each of these files & change the namespace specified in them to TestTemplate. Save the changes, close the files & then add Error.aspx & PageTemplate.cs to the project. Rebuild the project.
- Copy the resource files (MyResources.fr.resx & MyResources.resx) into the TestTemplate directory & then add them to the project. Also, make sure that the resource files are properly specified in the
OnLoad()
method of PageTemplate.cs, i.e the following line in OnLoad()
Application["resources"]
= new ResourceManager("MyTemplate.MyResources",Assembly.GetExecutingAssembly());
now becomes
Application["resources"]
= new ResourceManager("TestTemplate.MyResources",Assembly.GetExecutingAssembly());
Rebuild the project.
- Add a new Web Form & call it FirstPage.aspx. This page will be the first aspx to be called in your site. Hence, this page will set the user id & language into the session.
In the HTML source for FirstPage.aspx, remove all HTML tags except for the form tags. i.e. your HTML source now looks like
<%@ Page language="c#" Codebehind="FirstPage.aspx.cs" AutoEventWireup="false"
Inherits="TestTemplate.FirstPage" %>
<form id="FirstPage" method="post" runat="server">
</form>
Add controls to the form in the designer mode. Do not add buttons to submit the form.
Set FirstPage.aspx as the start page of your project.
Change the code-behind's parent class from System.Web.UI.Page
to PageTemplate.
In the Page_Load
method, do the following
if ( IsPostBack )
{
}
else
{
string languageCode = "en";
string userID = "superman";
setLanguageAndUser(languageCode, userID);
}
HelpURL = "first_page_help.html";
- Run the project. You will see FirstPage.aspx with a lot of extras -
- Left menu
- Header
- Footer
- Search box
- Date information
- User Login information
- Continue, Restart & Exit hyperlinks
- Help hyperlink
- Now, change the language code to "fr" & look at it again. You will see that text for most labels have changed.
- The Continue hyperlink calls a JavaScript function -
continueForm()
. This method should be overridden in the HTML source of every aspx to submit the form. i.e. - you can include the following in the HTML source of the aspx page
<script>
function continueForm() {
alert("submitting......");
document.FirstPage.submit();
}
</script>
Now, see what happens when you click on Continue. Please note that you can provide alternate means to submit a form. I happened to use the Continue hyperlink.
- Handle an exception in
Page_Load
& see what happens. i.e. in the postback section -
if ( IsPostBack )
{
try
{
throw new Exception();
}
catch (Exception ex)
{
SetErrorCode(1);
}
}
You will see that on submitting, the page automatically gets redirected to the Error page. Also, a message picked up from the resource file is shown.
Also, when the session times out redirection to the error page(with error code) happens automatically.
- To add more pages is even easier -
- Add a new web form.
- Remove all HTML tags except for form tags. Add your controls.
- Change the parent of the code-behind to PageTemplate.
- Override
continueForm()
, if necessary.
- Provide functionality only pertaining to that page. Code for session checks, i18n setup, DB & utility class setups, error handling, etc are not required.
- You don't have to call
setLanguageAndUser()
in any page except for the first aspx page (i.e. FirstPage.aspx here).
- To change the HTML rendered by the template, modify the HTML source in the
Render
method of PageTemplate.