Overview
Most examples of ASP.NET Page Templates do not actually include the server Form. This is because it is expected that it will be placed in each Page that needs it. However, sometimes there is a need to include the server Form in the Page Template. This article provides examples with server Forms, although caution is recommended. I decided to write this article due to the number of people that have asked me to, but I feel strongly that a well-designed Page Template will seldom require this. The fact is that advanced implementations can get you in a lot of trouble fast, when usually a more simple design can avoid the complexities inherent in this.
Common Method
Both of the examples given here take advantage of the AddParsedSubObject method. This method is already internally used by ASP.NET when it parses an ASPX Page, with the implementation of this method being to add each control to the Page. However, this internal behavior can be overriden to something else as needed, with no measureable overhead since this is part of the normal Page processing. My article on
Designer Issues used this method to ignore some header/footer html. Both of these examples override this method to add each control to something else. The one catch is that this implies something has to exist to add each control to, so each example must first create (or load) a parent control in the Constructor.
User Controls
This example is just a small modification to the standard User Controls Template, which is detailed in
other articles and can be seen on my
Page Template Generator. The difference is that a server Form (type System.Web.UI.HtmlControls.HtmlForm) is declared in the base Page class, which is then instantiated in the Constructor. The AddParsedSubObject method is then overriden to add each control to the Form, which is then added to the Page itself, along with the header/footer, in OnInit. This method leaves the identifiers of the other server controls on the ASPX Page as they are defined in the ASPX Page itself, unlike the next example we will see. This all works quite well, although again I must caution that this is advanced.
Listing 1: User Controls
public class BasePage : System.Web.UI.Page
{
protected HtmlForm form;
protected override void OnInit(System.EventArgs e) {
this.Controls.AddAt(0, LoadControl("Header.ascx"));
this.Controls.Add(form);
this.Controls.Add(LoadControl("Footer.ascx"));
}
protected override void AddParsedSubObject(object obj) {
form.Controls.Add((Control)obj);
}
public BasePage() {
form = new HtmlForm();
form.ID = "frmMain";
}
}
Single Template
This example is based on a completely different approach to ASP.NET Page Templates, which is based on several postings by
Jacob Morgan on Microsoft's
ASP.NET Forums. The major difference here is that you do not see any of the usual events overriden, nor do you see separate user controls for the various regions of each ASP.NET Page. Instead, a single "Template" user control is loaded and used in the Constructor, which contains the header/footer, and any other regions, including the server Form. The AddParsedSubObject method is then overriden to add each control appropriately, in this case to a specific Content control that is defined in the "Template" itself. This is a great way to have a single Template, but I do continue to recommend caution.
Listing 2: Single Template
public class BasePage : System.Web.UI.Page
{
private Template template;
protected override void AddParsedSubObject(object obj) {
this.template.Content.Controls.Add((Control)obj);
}
public BasePage() {
if (this.Context != null) {
this.template = (Template)LoadControl("Template.ascx");
this.Controls.Add(this.template);
}
}
}
Conclusion
These examples provide two ways to include a server Form in your Page Template, although these are advanced techniques that should only be used where necessary. The fact is that most well-designed Page Templates do not include a server Form, although it may include additional regular html Forms for items like search/login. However, both of these methods do work and can be further extended to your needs, and both perform rather well due to the override of the AddParsedSubObject method. Note that using either of these techniques with a server Form tag in an ASPX Page will result in an Exception, since only one server Form can ever be in each Page.
Author Bio
Paul Wilson is a software architect in Atlanta, currently with PRG-Schultz. He specializes in Microsoft technologies, including .NET, C#, ASP, SQL, COM+, and VB. His
WilsonWebForm Control allows Multiple Forms and Non-PostBack Forms in ASP.NET. He is a Microsoft MVP in ASP.NET and is also recognized as an
ASPInsider. He is a moderator on Microsoft's
ASP.NET Forums, as well as one of the top posters. He is holds the MCSD, MCAD, MCDBA, and MCSE certifications. Please visit his website,
www.WilsonDotNet.com, or email him at
Paul@WilsonDotNet.com.