|
Comments
|
Today's Top SOA Links
ASP.NET Standardizing an ASP.NET Web Site
Standardizing an ASP.NET Web Site
By: Jeff Jorczak
Jan. 30, 2003 12:00 AM
In large Web sites, there are generally just a couple of unique page layouts. In the past, developers had to duplicate large chunks of code on each page. Doing so made the site hard to maintain and difficult to change on a global scale. This tended to be an issue even when using include files, as it was difficult to pass page-specific information down the chain. To the rescue are the .NET Web User Controls and their ability to interact with a parent page's exposed custom properties. Through an assortment of referenced custom controls, the look and layout of a site can be enforced and page differences can be controlled from one location on the parent page. Additionally, global site changes can then be made by simply changing a single control. In this article, I assume that you are familiar with the creation of ASP.NET WebForm pages and Web User Controls, and the use of the various other ASP.NET controls.
The Dark Ages <!-- #INCLUDE VIRTUAL="/site/includepage.asp" --> This method worked fine at first, but as the complexity of our sites increased, so did the issues involved with them. One such issue was that the included pages inherited the same environment as the parent page, so any variables declared would carry over, the original query string would carry over, etc. For some things this was good. For instance, you could define a variable "color" on the parent page, then on the included page reference it with: <%=color%> However, you could not transfer data to the include page through any query string values as in: <!-- #INCLUDE VIRTUAL="/site/include page.asp?color=red" --> Additionally, if you tried to assign or redeclare a variable, such as "color", on the included page, it would stomp on the parent page's value, or raise an error condition. With all this in mind, you can see that the old way was not very elegant, and was prone to errors. Tracking the cause of these errors was also very difficult since it was hard to trace the interdependence of these pages.
The Enlightenment In the simplest case, a Web User Control just contains a block of HTML code to place on a page wherever the control is referenced: <uc1:Control1 id="control1" runat="server" /> In a more complex case, a control exposes properties that can be set by the page when the control is referenced:
<uc1:Control1 id="control1" customProperty="green" This provides a more elegant means of communicating information into the control from the parent page. Both the page and control can use a variable called "color", but the value must be passed explicitly from the parent page to the control. No more stepping on each other's toes.
180-Degree Spin However, what if you have a site with hundreds of pages using the same controls several times per page? Every time the control appears on the page, you have to assign a value to the custom control properties. If you want to provide the same value to several controls, you will get something like this:
<uc1:Control1 id="control1" userName="Jeff" runat="server" /> Seeing the duplication of hard-coded values above should immediately raise a red flag. The problem is that if the userName changes, the value has to be changed in three different places. It would be much cleaner to simply be able to change it in only one place, and have every control on the page inherit the single value. Implementing that goal is what the remainder of this article is about. There really are two ways to achieve the goal of having page controls automatically gain access to a parent page's properties. I will start with the most elegant one, which is inheritance. However, there are problems with using this technique in Visual Studio, so I will also provide an alternative method, which is through the use of an interface.
The Project
private System.Drawing.Color color; These consist of the color scheme and the title of the page. Since the variables are private, they need to be exposed to code outside the page through the following public property blocks:
public string Title The three pages that I created are "PageRed", "PageGreen", and "PageBlue", which utilize the same three controls. The controls look different on each page, however, depending on the values of each page's custom properties. Figures 2, 3, and 4 show the changes on each page: the title text and color, the menu area color, and the name of the color in the content area. The code defining the page properties looks simple enough at first, but our controls still cannot access these properties directly. Since a WebForm page inherits from System.Web.UI.Page, and the Page class does not implement a "Color" or "Title" property, a control will raise an exception if it tries to do something like the following: System.Drawing.Color localColor = Page.Color; So, how can we get the controls to see these properties? The answer is inheritance.
Base (Template) Page Class BasePage inherits from System.Web.UI.Page as usual, and implements the two new properties that we desire to have on every page. Once this is created, we have each of our pages inherit from this new class instead of the built-in Page class. Each of our page class declarations look like the following:
public class PageGreen : BasePage We need to be able to set properties on a page level, then allow included controls to find and access them. All of our pages will now automatically inherit support for our two custom properties. Additionally, there is now a mechanism for our controls to expect and find these properties, which I will cover in the next section. Since the pages automatically inherit the two properties, we can simply assign a value to them once on each page's Page_Load handler:
private void Page_Load(objectsender, System.EventArgs e)
Controls
private void Page_Load(objectsender, System.EventArgs e) The control gets the Page property, which is expected to be of type System.Web.UI.Page, and instead treats it like a BasePage type, which it actually is. Now the two properties are available for access. That's all there is to it. We created a new base page class that defines all the custom public properties that a page will expose. We inherited from that page on each of our real pages, and we assigned values to the properties in its Page_Load handler. Then each control that needs a value from the page gets its Page property, casts it as our base page, and accesses the custom property values.
Issues and an Alternative In the real world, I found that the ability to use the visual design tools outweighs the elegance of inheritance. Luckily, there is another solution almost as nice that works flawlessly the implementation of a custom interface. Instead of creating a base page to inherit from, we will define our properties through an interface and require that each page implement that interface. This allows us to cast the page in each control as the interface with the same result as using a base page class. The drawback is that we have to implement the properties on every page, rather than just on a single page that we inherit from. So, the interface is defined through a simple .cs file as:
public interface IPageTraits It tells all our pages that they have to implement a set and get function for the two properties we want them to expose. Each page declaration will then appear as shown in Listing 2 and will be required to implement the two properties of the interface. Notice that our pages inherit from System.Web.UI.Page and also implement IPageTraits. C# can only inherit from one parent class, but it can implement any number of interfaces. It would be nice to have multiple inheritance in C# because we could inherit from page as well as another class that has our custom properties, but that is not an option. Our control code then needs only to cast the page as an IPageTraits object to access our properties:
private void Page_Load(objectsender, System.EventArgs e)
Conclusion Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
|||||||||||||||||||||||||||