Each ASP.NET page inherits from System.Web.UI.Page; however,
a custom page class can inherit from this System.Web.UI.Page, and all ASP.NET
pages can inherit from this custom page. This custom page class is a great
feature because it can provide generic or specialized properties/methods that
are useful to an application or a specific page. User controls work the same
way; a custom UserControl class can be used, which can expose properties/methods
to all of the user controls in a web application. Throughout this article the
custom page class and custom user control class that serves as an intermediary
will be referred to as "the custom page class" or "the user
Unit testing has several complications when testing against an
ASP.NET page. First, this approach usually involves the unit test inheriting
from the ASP.NET page. In addition, ASP.NET utilizes a different set of runtime
objects (Handlers/Modules) that are available in the web environment and not in
the unit testing environment. For instance, the session object makes use of a module
that is not available normally in the test environment. Creating a custom
session factory for testing purposes only can be overly complicated and not
worth the effort it takes to develop one for unit testing purposes. In
addition, the request/response collection is also specialized to the web
environment, and not available in the unit testing environment. Caching is not
the same, because one can make use of the Enterprise Library Caching block,
which works in the windows realm as well.
The ASP.NET default model can also provide additional
complications. Within a custom page or user control class, ASP.NET controls can
be exposed, but simple and complex properties, templates, and other
server-control settings may not be directly accessible in code-behind. In
addition, what happens when a custom user control base class is reused between
multiple user controls? The markup code has to be duplicated. For instance,
take the markup below.
<asp:GridView id="gvwProducts" runat="server" AutoGenerateColumns="false"
<asp:BoundField HeaderText="ID#" DataField="ProductID" />
<asp:BoundField HeaderText="Name" DataField="ProductName" />
<asp:BoundField HeaderText="Cost" DataField="Cost" />
The GridView control has three columns, all in the markup.
However, if the page or user control is considered reusable, a better implementation
is to move the setup of the GridView to the page or user control class, and
create them at runtime.
There are good reasons to do this: creating them in the
custom page or user control class increases reusability, increases how much the
page/user control class knows about the server controls, and increases how much
can be manipulated. The drawbacks are, as I stated before, extra coding effort.