With John's application fully implemented from front to back, the final phase of implementation can now be completed: Tom's presentation layer. Tom's application has a more complex front end, including a shopping cart and dynamic page generation. By the end of this article you should have two fully implemented and functional applications.
Lay the foundation
Before you begin implementation of the use cases I need to lay out some basic structure to the front end. Tom's application will use the same three basic components as John's application: a Stylesheet, custom navigation control, and an ASPX identifier. Additionally, Tom's application will require separate subfolders for the ASPX pages, a stateful session object, and a custom error page.
Web services B2B implementation demonstration
Welcome to the seventh article in a 10-part series exploring in detail the implementation of a B2B Web service. The series takes you through the development of a complete B2B Web services application. During the course of the series we encourage Builder.com members to comment on the progress of the application. Do you have a better implementation? Do you have a question about our B2B solution? Start an article discussion and let us hear from you; we will do our best to address the issue.
Want to catch up on the series?
- "Web services B2B implementation demonstration: Setting the scenario"
- "Web services B2B implementation demonstration: Components, exception handling, and logging"
- "Web services B2B implementation demonstration: Database design"
- "Web services B2B implementation demonstration: John's business logic"
- "Web services B2B implementation demonstration: Tom's business logic"
- "Web services B2B implementation demonstration: John's ASPX GUI layer"
Open Tom's ASP.NET solution and replace the contents of the default Styles.css file with the contents in Listing A (link to Styles.css). Tom's stylesheet employs the same basic structure as John's but adds a different flavor of color and fonts.
Next you'll add the ASPX identifier class. Right-click Tom's ASP.NET project and select Add | Add Class. Name this new class WebPageNames.vb and paste the contents from Listing B into this class. As with John's application, identify each ASPX page in the application through a static constant to avoid hard coded page references.
To create separation between the public and private areas of the website, you need to create two subfolders. Right-click Tom's application and select Add | New Folder. Repeat this process twice to create two folders named: "public" and "private". Pages that are available only to Tom's registered customers will be placed in the private folder; all other pages will be placed in the public folder.
Because Tom's application implements a simple shopping cart, you need to add some basic state management to the application. Instead of stuffing several variables into the session object, package the variables you need into a new class and place one single instance of this class into the session for cleaner management.
To implement this class, right-click Tom's application and select Add | Add Class. Name this new class SessionObj.vb and paste the contents from Listing C into this class.
The SessionObj class is responsible for managing information regarding a customer, as well as any books they've added to their shopping cart. Add the following code to the Global.asax file to generate a new session object for each user when he enters the application:
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Initialize the shopping cart numeric tracking variable
Session.Add(ClientSession.CLIENT_SESSION_REF, New ClientSession())
For the navigation bar you'll implement a simple row of buttons which will reside at the top of each page allowing users to navigate around the application. A small addition to the navigation bar will be made to show the number of items currently in the user's shopping cart. The NumItems variable in the SessionObj class maintains a count of the number of books the customer has placed in his shopping cart.
To add the navigation bar, right-click the public folder and select Add | Add Web User Control. Name this control NavBar.ascx and add the HTML code from Listing D to the HTML view of the control, and the VB.NET code from Listing E to the code behind file.
Next you need to enable security for this application. You'll use Forms authentication to protect the pages in the private folder. Right-click the private folder and add a new Web.config file to this directory, replacing the contents of the file with the code in Listing F (link to PrivateWeb.config). This will ensure only authenticated users will have access to the pages in the private directory.
On the main Web.config file in the root of application, replace the default authentication node with the following code:
<forms name=".WSB2BTomCookie" loginUrl="public/LoginForm.aspx" protection="All" timeout="30" path="/">
Finally, you need to implement a user friendly error page. Whenever an error occurs in the application, you redirect users to a page with a user friendly error message. To implement this, replace the customErrors node in the root Web.config file with the following code:
<customErrors mode="RemoteOnly" defaultRedirect="Error.aspx" />
To add the error page, right-click Tom's application and select Add | Add Web Form. Name the new page Error.aspx and replace the HTML contents of this file with the contents from Listing Q (link to Error.aspx).
The ASPX pages
Now you're ready to begin adding your ASPX pages to the application. As with John's application, you'll first add all of the pages and get the code pasted into them, and then take a review of the important aspects of each ASPX. Right-click the appropriate folder and select Add | Add Web Form for the pages outlined in the table below. For each page, copy the link from the HTML column of Table A into the HTML view for the page, and the code from the Code Behind column into the code behind class for the page.
This page is available to all users. It contains a search form, and a results datagrid. When the page loads, it retrieves a dataset of valid availabilities from John's application through a Web service. The interesting thing to note is that Tom's application will automatically update should these values ever change in John's application, and Tom would never need to modify his application to reflect these updates. This is one of the benefits of a Web services enabled B2B application.
Once search criteria are provided, another call is made to John's Web service to search his inventory. The results are placed into the datagrid for presentation to the user. The user can then order a book by clicking the Order button, which places the information regarding that book into their SessionObj object.
By default all requests made to pages in the private folder by unauthorized users will be redirected to this page. If a user has a customer account already created, they can enter their credentials which are then validated against Tom's database. If authenticated, their information is placed into their SessionObj object and they are redirected back to the secured page they initially tried to reach, otherwise they are taken to ViewCart.aspx by default. Additionally, a security cookie token is created for them which will allow ASP.NET to authenticate the user on subsequent requests to secured pages.
For users who do not have a customer account with Tom, this page allows them to create a new customer profile. The users' email is used as their login ID.
This page allows authenticated users to manage their shopping cart. Again, by creating a B2B Web service link between Tom and John, all information regarding the books and the customers' orders is maintained at an invisible level. Tom's application never needs to do any maintenance to his application to reflect changes in orders and book information.
From this page users can view which books they've placed in their shopping cart, how much the total order will cost, and they may remove books from their cart. Once a user places an order by clicking the "Place Order" button, an asynchronous call is made to John's application, and a transaction handoff is made. John is now responsible for the order from this point. The customer's shopping cart is then cleared, and the user can continue shopping.
This page provides customers with information regarding orders they've placed. The contents of this page are rendered dynamically on-the-fly. The view is split into two presentation tables, one for orders that are pending processing, and the other for orders that have been completed. Because basic information regarding an order is stored in Tom's application it can easily be used to determine the status of the customer's order. By placing an additional call to John's application, specific details can be retrieved for a given order.
The tables are presented in groups by order. Each order can contain many books so the presentation reflects this relationship to present a user friendly cohesive set of orders. The creation of the content for this page is a simple example of how to generate controls at run time and display them to the user. Getting the layout correct can be difficult but with some trial and error, you can generate pages dynamically with relative ease.
Next in the series
In the eighth installment of Kevin Koch's Web services B2B implementation demonstration, he will look into the debug and release configurations, create a deployment script, cover the principles of a production environment, and explain the principles behind the staging and production configurations.