Implementing the Basic Patterns in ASP.NET
The previous sections briefly describe five common and simple types of design pattern. While they are not generally explained in terms of ASP.NET, they are all applicable to ASP.NET and reasonably easy to implement. In fact, ASP.NET and the .NET Framework automatically implement several of them. Figure 5 shows schematically how these patterns relate to ASP.NET applications.
|Figure 5. ASP.NET Design Patterns: The schematic shows how ASP.NET implements some basic design patterns.
ASP.NET and the Model-View-Presenter Pattern
The ASP.NET code-behind technology, which uses partial classes, provides a natural implementation of the MVP pattern. The code-behind file (the Presenter) contains all the logic and processing code, and populates the page (the View). Event handlers within the code-behind file handle events raised by controls or by the page itself to perform actions when a postback to the server occurs. To complete this pattern, the code-behind file can use a separate data access layer or component (the Model) to read from, write to, and expose the source data—usually accessed through built-in providers that are part of the .NET Framework.
For example, a page might use a separate class that exposes methods to read and update a database table. This class might use the SqlClient, OleDb, or another data provider to connect to the database and execute dynamic SQL queries or stored procedures. The code in the code-behind file uses this class to retrieve the data, and populates the controls defined in the ASPX file that generates the user interface. When the user interacts with controls in the page, perhaps changing values in the data, code in the code-behind file executes during the postback and uses the data access class to push the changes back into the database.
|Figure 6. MVP Implementation: The View shown here (the Default.aspx HTML page) gets its data from the Presenter (the ASP.NET page), which collates and formats the data from the Model (the data access layer and database).
The sample application uses the code-behind model throughout, thereby implementing the MVP pattern on each page. The default page (Default.aspx) demonstrates the ASP.NET application of the MVP pattern by displaying a View that contains a series of controls that allow users to execute any of a range of functions that fetch and display data (see Figure 6).
Clicking one of the buttons causes a postback to the server and raises the event that corresponds to that button. For example, the interface component for the second button shown in Figure 6 is an ASP.NET Button control, declared within the View (the ASPX page), which initiates an event handler named btn_CustModel_Click in the Presenter (the code-behind file) to handle the Click event:
<asp:Button ID="btn_CustModel" runat="server"
Get name for customer
<asp:TextBox ID="txtID_CustModel" runat="server"
Text="ALFKI" Columns="3" />
from CustomerModel<p />
The Presenter (the code-behind file) contains the declaration of the btn_CustModel_Click method, which creates an instance of the Model (a class file named CustomerModel.cs in the App_Code folder) and calls one of its methods to get the name of the customer identified by the customer ID users enter into the text box next to that button:
protected void btn_CustModel_Click(object sender, EventArgs e)
// display the name of the specified customer
// use method of the CustomerModel class
CustomerModel customers = new CustomerModel();
Label1.Text += "Customer Name from CustomerModel class: ";
Label1.Text += customers.GetCustomerName(
catch (Exception ex)
Label1.Text += "PAGE ERROR: " + ex.Message;
Label1.Text += "<p />";
You can view the contents of the files Default.aspx (the View), Default.aspx.cs (the Presenter), and CustomerModel.cs (the Model) that implement the MVP pattern in this example to see all the UI control declarations and code they contain. As you saw in Figure 6, there are buttons to execute a range of CustomerModel methods, as well as methods of the Repository, Web Reference, and Service Agent implementations discussed in the following sections.
|Notice that the Default.aspx page (see Figure 6) contains a drop-down list where you can select a page or view you want to see. The application loads the selected page using an implementation of the Front Controller pattern, described in more detail in the next article in this series. For now, it's sufficient to explain that you can use the drop-down list to navigate to other pages to see the examples, such as the Use Case Controller example page or the Publish-Subscribe example page.
ASP.NET and the Provider Pattern
ASP.NET uses the Provider pattern in a number of places. These include providers for the Membership and Role Management system (such as the SqlMembershipProvider and SqlRoleProvider), the Site Navigation system (the XmlSiteMapProvider), and the user profile management system (such as the SqlProfileProvider). The various data access components provided with ASP.NET, such as the SqlDataSource, also rely on providers. These providers are part of the .NET Framework data-access namespaces, and include SqlClient, OleDb, Odbc, and OracleClient.
Each provider is configured in the web.config file, with the default settings configured in the server's root web.config file. Developers can create their own providers based on an interface that defines the requirements, or by inheriting from a base class containing common functionality for that type of provider. For example, developers can extend the DataSourceControl class to create their own data source controls that interface with a non-supported or custom data store.
ASP.NET and the Adapter Pattern
ASP.NET uses adapters to generate the output from server controls. By default, server controls use adapters such as the webControlAdapter or DataBoundControlAdapter to generate the markup (such as HTML) and other content output by the control. Each adapter provides methods such as Render and CreateChildControls that the server controls call to create the appropriate output.
Alternative adapters are available, for example the CSS Friendly Control Adapters provide more flexibility for customizing the rendered HTML. Developers can also create their own adapters to provide custom output from the built-in controls, or from custom controls.