Browse DevX
Sign up for e-mail newsletters from DevX


Design Patterns for ASP.NET Developers, Part 2: Custom Controller Patterns : Page 3

If any part of your ASP.NET applications display pages based on user interaction, browser type, security permissions, or other factors, you'll find these Controller patterns useful.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Implementing the Use Case Controller Pattern
The example implementation of the Use Case Controller pattern uses a single ASPX page (TransferPage1.aspx), with a code-behind file that implements the Presenter. If the page load was caused by a postback (a user clicked one of the buttons in the page), code in the Page_Load event of the Presenter extracts the name of the partial View (the user control) to display from the page's ViewState, and saves this in a local variable named viewName. When the page load is not a postback, the code just sets viewName to the default value "CustomerList" and calls the method LoadAndDisplayView within the Presenter:

public partial class TransferPage1 : System.Web.UI.Page { String viewName = String.Empty; protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack) { // get current view name from page viewstate viewName = (String)ViewState["ViewName"]; } else { viewName = "CustomerList"; LoadAndDisplayView(); } // display actual URL of currently executing page lblActualPath.Text = Request.CurrentExecutionFilePath; String qs = Request.QueryString.ToString(); if (qs != null && qs != String.Empty) { lblActualPath.Text += '?' + qs; } } ...

The remaining code in the Page_Load event displays the actual URL of the current page and any query string, so that you can see the effects of the Front Controller when it redirects requests to different pages. You will see how the Front Controller works in the next article in this series.

To load and display a user control dynamically, code in the LoadAndDisplayView method creates a new instance of the control and then adds it to the Controls collection of an ASP.NET Placeholder control located in the main View (the ASPX page). After displaying the user control, the code sets the Enabled properties of the "Back" and "Next" buttons, depending on the current view name, and displays the name of the view in the page header element (a <div> control with the runat="server" attribute). Finally, it saves the name of the view in the page ViewState to get ready for the next postback:

private void LoadAndDisplayView() { // load and display the appropriate view if (viewName != null && viewName != String.Empty) { try { UserControl view = (UserControl)LoadControl(viewName + ".ascx"); viewPlaceHolder.Controls.Add(view); } catch (Exception ex) { throw new Exception( "Cannot load view '" + viewName + "'", ex); } } else { viewName = "No view specified"; } // set state of buttons to match view btn_Back.Enabled = (viewName != "CustomerList"); btn_Next.Enabled = (viewName != "CityList"); // display name of current view pageHeaderElement.InnerText = "Current View is '" + viewName + "'"; // save in page viewstate for use in postback ViewState["ViewName"] = viewName; }

As an alternative, you could use the Server.Execute method to execute separate ASPX pages, each an MVP pattern implementation with its own Presenter (code-behind file) and View (ASPX page) that generates the appropriate output. This output will appear in the resulting page as a partial View, though you must remember not to include the <html>, <head>, and <body> elements in the partial View implementation.

However, it is likely that you will have to include the ASP.NET <form runat="server"> section in the partial View to be able to use ASP.NET web controls in that page—which means that you can only use one partial View per hosting page. User controls are more likely to be easier to manage, and more efficient. Each can contain its own initialization code, and does not require a <form> section. Neither do they, by default, contain the <html>, <head>, and <body> elements.

The only other code the Presenter requires is button-click handlers. The event handlers for the "Back" and "Next" buttons change the value of the viewName local variable, and then call the LoadAndDisplayView method to display the current view. The event handler for the "Cancel" button just redirects the request back to the default page of the example application:

protected void btn_Back_Click(object sender, EventArgs e) { switch (viewName) { case "CustomerDetails": viewName = "CustomerList"; break; case "CityList": viewName = "CustomerDetails"; break; } LoadAndDisplayView(); } protected void btn_Next_Click(object sender, EventArgs e) { switch (viewName) { case "CustomerList": viewName = "CustomerDetails"; break; case "CustomerDetails": viewName = "CityList"; break; } LoadAndDisplayView(); } protected void btn_Cancel_Click(object sender, EventArgs e) { Response.Redirect("Default.aspx"); }

To see the results, look back at Figure 4, 5, and 6. These show the three views that the Use Case Controller example displays as you click the "Back" and "Next" buttons.

Author's Note: You can open the Use Case Controller page by selecting either "Use Case Controller" or "TransferPage1.aspx" in the dropdown list at the bottom of the Default.aspx page of the sample application.

Thanks for your registration, follow us on our social networks to keep up-to-date