Paulo Morgado

.NET Development & Architecture

This Blog

Syndication

Search

Sponsored By

Tags

News

Unit Test Today! Get Typemock Isolator!

Projects

Books

 

Visitors

Visitor Locations

Community

Email Notifications

Archives

Profile

Disclaimer

The opinions and viewpoints expressed in this site are mine and do not necessarily reflect those of Microsoft, my employer or any community that I belong to. Any code or opinions are offered as is. Products or services mentioned are purchased by me, made available to me by my employer or the manufacturer/vendor which doesn't influence my opinion in any way.

Page Flow Application Block With Page Modules

Introduction

In this article I will demonstrate how a web application can benefit from the use of Page Modules using, for the demonstration, the Page Flow Store Quick Start and the Page Flow Application Block shipped with the Web Client Software Factory.

Creating the Page Module

The first step is creating a Page Module that will replace the HTTP Module used by the Page Flow Application Block.

Since the Page Module will only be called for pages (.aspx), there is no longer need to register extensions for pages and check in every HTTP Request if the request is for a page making the PageFlowPageModule simpler that the PageFlowHttpModule.

namespace PauloMorgado.Practices.PageFlow.Extensions
{
    public class PageFlowPageModule : PauloMorgado.Web.UI.IPageModule
    {
        #region IPageModule Members

        public void Init(PauloMorgado.Web.UI.PageHandlerFactoryWithModules context)
        {
            context.PageCreated += new System.EventHandler<PauloMorgado.Web.UI.PageCreatedEventArgs>(OnPageCreated);
        }

        #endregion

        void OnPageCreated(object sender, PauloMorgado.Web.UI.PageCreatedEventArgs e)
        {
            int rootSplitter = e.VirtualPath.IndexOf('/', 1);
            string path = '~' + e.VirtualPath.Substring(rootSplitter);
            Microsoft.Practices.PageFlow.ProcessResult result = Microsoft.Practices.PageFlow.PageFlowDirectory.Provider.ProcessRequest(path);
            if (result.ShouldRedirect)
            {
                System.Web.HttpContext.Current.Server.Transfer(result.RedirectUrl, false);
            }
        }
    }
}

Registering the Page Module

Now that I have a Page Module, I just need to replace the HTTP Module with it.

The first step is registering the PageHandlerFactoryWithPageModules as the handler factory for *.aspx requests:

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <configSections>
        <sectionGroup name="PauloMorgado.web">
            <section name="pageModules"
                     type="PauloMorgado.Web.Configuration.PageModulesSection, PauloMorgado.Web.UI.PageHandlerFactoryWithModules"/>
        </sectionGroup>
    </configSections>
    <system.web>
        <!-- 
            ...
        -->
        <httpHandlers>
            <remove verb="*" path="*.aspx"/>
            <add verb="*" path="*.aspx" validate="false"
                 type="PauloMorgado.Web.UI.PageHandlerFactoryWithModules, PauloMorgado.Web.UI.PageHandlerFactoryWithModules"/>
        </httpHandlers>
        <!-- 
            ...
        -->
    </system.web>
    <PauloMorgado.web>
        <pageModules>
        </pageModules>
    </PauloMorgado.web>
</configuration>

The second step is registering the PageFlowPageModule as a Page Module:

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <!-- 
        ...
    -->
    <PauloMorgado.web>
        <pageModules>
            <add name="PageFlowModule"
                 type="PauloMorgado.Practices.PageFlow.Extensions.PageFlowPageModule, PauloMorgado.Practices.PageFlow.Extensions"/>
        </pageModules>
    </PauloMorgado.web>
</configuration>

And, finally, I need the remove the PageFlowHttpModule from HTTP Modules list:

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <!-- 
        ...
    -->
    <system.web>
        <!-- 
            ...
        -->
        <httpModules>
            <!--<add name="PageFlowModule"
                         type="Microsoft.Practices.PageFlow.PageFlowHttpModule, Microsoft.Practices.PageFlow"/>-->
        </httpModules>
        <!-- 
            ...
        -->
    </system.web>
    <!-- 
        ...
    -->
</configuration>

Changing the Navigation Service

One of the benefits of using Page Modules is that there is no longer the need to issue client-side redirects to navigate to another page. For that reason, the only change need in the navigation service is replacing the call to the HttpResponse.Redirect method for a call to the HttpServerUtility.Transfer method.

public void RedirectTo(Page page)
{
    Guard.ArgumentNotNull(page, "page");
    HttpContext.Current.Server.Transfer(page.Url, false);
}

Testing the Page Flow Page Module

Now that I have it all set up, all I need is run it.

For the purpose of the demonstration I'll compare the results between the usage of an HTTP Module and a Page Module.

The Use Case

The test the application I'll do a simple shopping session that consists of the following steps:

  1. Login
  2. Start the page flow
  3. Browse the catalog
  4. Add an item to the shopping cart
  5. Checkout the order
  6. Enter payment data
  7. End the shopping session

Analyzing the steps

Screen

With HTTP Module

With Page Module

Comments
  Page Flow Quick Start With HTTP Module - Step 1 Page Flow Quick Start With Page Module - Step 1

The first request just gets the first page.

Page Flow Quick Start - Step 1     The user enters the credentials and presses the Log In button.
  Page Flow Quick Start With HTTP Module - Step 2 Page Flow Quick Start With Page Module - Step 2

The second page is the login page.

As usual with FormsAuthentication, the request is redirected via a client side redirection.

At this point there are still no changes in the behavior of the application.

 Page Flow Quick Start - Step 2     The user presses the Start Store Page Flow button.
  Page Flow Quick Start With HTTP Module - Step 3 Page Flow Quick Start With Page Module - Step 3

This is were we start noticing the changes.

As you can notice, with the HTTP Module, the navigation to the next page is issued via a client side redirection.

On the other hand, with the Page Module, the navigation is done server side saving one request.

 Page Flow Quick Start - Step 3     The user presses the Browse Catalog link button.
  Page Flow Quick Start With HTTP Module - Step 4 Page Flow Quick Start With Page Module - Step 4

With the HTTP Module, the navigation to the next page is issued via a client side redirection.

With the Page Module, the navigation is done server side saving one request.

Page Flow Quick Start - Step 4     The user selects a product by pressing the Add to cart link button.
  Page Flow Quick Start With HTTP Module - Step 5 Page Flow Quick Start With Page Module - Step 5

With the HTTP Module, the navigation to the next page is issued via a client side redirection.

With the Page Module, the navigation is done server side saving one request

Page Flow Quick Start - Step 5     The user presses the Checkout Order link button to complete the shopping session.
  Page Flow Quick Start With HTTP Module - Step 6 Page Flow Quick Start With Page Module - Step 6

With the HTTP Module, the navigation to the next page is issued via a client side redirection.

With the Page Module, the navigation is done server side saving one request

Page Flow Quick Start - Step 6     The user enters the payment data and presses the Submit Order button.
  Page Flow Quick Start With HTTP Module - Step 7 Page Flow Quick Start With Page Module - Step 7

With the HTTP Module, the navigation to the next page is issued via a client side redirection.

With the Page Module, the navigation is done server side saving one request

Page Flow Quick Start - Step 7     The shopping session is completed.

The complete navigation charts are here:

With HTTP Module

With Page Module

Page Flow Quick Start With HTTP Module Page Flow Quick Start With Page Module

Conclusion

With this simple example is already possible to show the benefits of using Page Modules. The reasons for this I already explained here.

In a real life scenario the benefits tend to increase because more complex page flows can be defined, with navigations being triggered by application logic instead of just user direct action without the concern for the weight of client side redirections.


Images captured with SnagIt. Page traffic captured with IEWatch.

Published Thu, Sep 27 2007 9:15 by Paulo Morgado

Comments

# re: Page Flow Application Block With Page Modules@ Thursday, October 04, 2007 4:12 AM

Page modules uses Server.Transfer(), instead of using Response.Redirect().

My Question is...How to deal with Query Strings?

This approch seems to cause problems with Query Strings.

Please clarify this.

Regards,

Pradeep (ypradeep23@hotmail.com)

Pradeep

# re: Page Flow Application Block With Page Modules@ Thursday, October 04, 2007 4:43 AM

I would say pretty much the way you would do with Response.Redirect().

What kind of problems are you expecting to have with Server.Transfer() that you don't have with Response.Redirect()?

Paulo Morgado

# re: Page Flow Application Block With Page Modules@ Thursday, October 18, 2007 1:25 PM

What will the user see in the URL if you only use Server.Transfer()?  

Phil

# re: Page Flow Application Block With Page Modules@ Thursday, October 18, 2007 3:22 PM

The user will see the requested URL, which is not a problem at all if you are using Page Flow Navigation.

Paulo Morgado

# Page Flow Application Block With Page Modules@ Thursday, November 01, 2007 2:19 PM

If you want to see how you can use Page Modules and its benefits, read this .

Paulo Morgado

# http://ajaxninja.com/?p=191@ Tuesday, January 15, 2008 4:19 PM

TrackBack

# http://dotnetkicks.com/users/paulomorgado/submitted@ Tuesday, January 15, 2008 4:21 PM

TrackBack

# http://dotnetkicks.com/aspnet/page_flow_application_block_with_page_modules@ Tuesday, January 15, 2008 4:22 PM

TrackBack

# Page Flow Application Block With Page Modules@ Saturday, February 02, 2008 1:34 PM

If you want to see how you can use Page Modules and its benefits, read this .

Paulo Morgado

Leave a Comment

(required) 
(required) 
 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: