Tony Northrup walks you through how to design your application architecture in this chapter from MCPD 70-519 Exam Ref: Designing and Developing Web Applications Using Microsoft .NET Framework 4.

The highest level aspect of the design process is also the most exciting: designing the application architecture. In this stage, the application begins to come to life, and you are not getting bogged down in technical details. You create a logical design for your application and then map the logical layers to physical servers. After you determine the physical layout, you can choose interapplication communication mechanisms and plan for cross-cutting concerns, such as systems administration.

Further into the design process, you choose how presentation logic will be divided between the client and server. For client-side components, you will need to decide between basic JavaScript, jQuery, Microsoft AJAX, and Microsoft Silverlight. For server-side components, you will need to choose between HTML controls, server controls, user controls, and Web Parts.

Finally, you will need to decide how to implement various state-management tasks. The Microsoft .NET Framework provides a wide variety of technologies, including application state, session state, view state, cookies, and caching.

IMPORTANT: HAVE YOU READ PAGE XIX?

It contains valuable information regarding the skills you need to pass the exam.

Objectives in this chapter:

Objective 1.1: Plan the Division of Application Logic

Objective 1.2: Analyze Requirements and Recommend a System Topology

Objective 1.3: Choose Appropriate Client-Side Technologies

Objective 1.4: Choose Appropriate Server-Side Technologies

Objective 1.5: Design State Management

Real World

The application design process starts when management determines that a new application can fulfill a business requirement. As management describes what they need from the new application, your mind will race with all the reasons the application won’t work the way they want. Pointing out every potential problem might feel like you’re demonstrating your technical skill and preventing future frustrations, but in the real world, it hinders the design process, dampens creativity, and annoys management.

As developers, our minds have been tuned to spot and eliminate flaws. However, you need to be creative and positive during the application design process. Do your best to ignore the low-level challenges; troubleshooting is a job for coders. Designers must create.

Objective 1.1: Plan the Division of Application Logic

In the early days of the web, browsers did little more than render HTML and display images. Today, thanks to technologies such as JavaScript, Flash, and Silverlight, the browser can interact with the user, validate data, and communicate with servers without loading new webpages. Use these client-side capabilities properly, and you can make your web application feel faster, reduce bandwidth, and reduce user input errors.

Server-side processing still has its place, however. First, server-side code is much easier to develop, test, and maintain. Second, anything but the most trivial data validation must be performed on the server, because it is possible for malicious attackers to bypass client-side validation. Third, some clients do not support JavaScript, Flash, or Silverlight, requiring you to duplicate any mandatory client-side functionality on the server.

This objective covers how to:

Choose whether to implement functionality on the client or server.

Efficiently use client-side scripting languages.

Explain the capabilities and drawbacks of rich, client-side plug-ins such as Flash and Silverlight.

Partition applications according to the separation of concerns principle.

Plan for long-running processes.

Choosing Between the Client Side and Server Side

Many tasks can be performed at either the client or the server. For example, if you ask the user to enter his address in a web form, you can provide a DropDownList named CountryDropDownList that contains every country/region in the world. When the user selects a country, you can populate the StateDropDownList with a list of states or provinces in his country.

You can do this on either the server or the client:

Server. In ASP.NET, set CountryDropDownList.AutoPostBack to True. In the DropDownList.SelectedIndexChanged event handler, populate StateDropDownList.

Client. Create a JavaScript function that handles the CountryDropDownList.OnChange JavaScript event and populates the StateDropDownList on the client.

Neither approach is clearly superior, but they each have advantages. By populating the list on the server side, you keep more code in ASP.NET, which is generally easier to write, troubleshoot, and maintain than JavaScript. Additionally, server-side processing works when the client does not support JavaScript.

By populating the list on the client side, you improve performance for both the user and the server. Client-side processing avoids a browser postback to the server when the user selects her country. This eliminates a delay in data entry that could last several seconds. Additionally, by reducing the number of requests sent to the web server, it reduces the performance impact on the server, thus improving scalability.

EXAM TIP

The 70-519 exam does not require you to know JavaScript or Microsoft AJAX; those topics were covered by the 70-515 exam. In fact, the 70-519 exam does not require you to know how to write code at all. You do need to know the capabilities and limitations of JavaScript and AJAX, however, and have a higher-level understanding of the impact of writing different types of code.

Table 1-1 compares common tasks that can be performed at either the client or server, and how you write code to accomplish them. When validating user input, you typically validate it on the client (for immediate responsiveness) and again at the server (for security and for browsers that do not support JavaScript).

Table 1-1. Performing Different Tasks at the Client-side and Server-side

Many tasks should always be done on the server, while other tasks should be performed on the client (when the client supports JavaScript). Table 1-2 lists tasks that can be done on the client, and situations that require you to perform the task on the server, instead.

Table 1-2. Client-side and Server-side Tasks

Client-side Tasks

Server-side Tasks

For convenience, notify users if they enter data in an invalid format. For example, if they enter too few numbers for a credit card.

For security and data integrity, verify that user data falls within specified bounds.

Dynamically add items to a menu, based on what the user does within a single webpage.

Add items to a menu for restricted pages that only authorized users can access.

Perform tasks that require access to the client computer, such as saving files using JavaScript or accessing the graphical processing unit (GPU) with Silverlight.

Perform tasks that require access to resources on the internal network that the server can access but are not exposed to the client.

Perform tasks that consume a great deal of bandwidth when communicating between the client and server.

Perform tasks that cannot be performed on the client, especially when the client lacks JavaScript, Flash, or Silverlight.

Process business logic that the end user is allowed to examine (because the user can access the source code).

If a task can be performed on either the client or the server, you should perform the task on the server because server-side programming is more efficient, the code is easier to debug, and the application is easier to maintain. Table 1-3 describes the key differences between client-side and server-side programming.

Table 1-3. Comparison of Client-side and Server-side Programming

Client-side Programming

Server-side Programming

Code is written in Microsoft Visual Studio 2010 with limited support for auto-complete.

Code is written in Visual Studio 2010 with full support for auto-complete, descriptions of all parameters, and integrated documentation.

Weak typing and run-time detection of errors.

Strong typing with compile-time detection of many errors

Must test in every supported operating system, browser, and browser version (which can be more than a dozen different environments).

Partitioning According to Separation of Concerns

Separation of Concerns (SoC) is a software architecture concept for dividing code used for different purposes. For example, if you were designing a web application with SoC in mind, you might create different application layers for the user interface, the business logic, the data access, and the database itself.

Microsoft’s early web development languages provided little opportunity for implementing SoC. However, the importance of SoC is reflected in each new web development model that Microsoft has released, as the following sections describe.

Classic ASP

In 1998, Microsoft released Active Server Pages (ASP), now known as Classic ASP. Classic ASP mixed the HTML user interface and all back-end code into a single file. To write output to part of a webpage, you had to write code at the appropriate spot in the HTML:

Because all the code was mixed together, a web designer who wanted to modify the user interface might accidentally change code that performed business logic or accessed the database. Similarly, if a database designer changed the layout of a table in the database, it might affect the user interface of the application. Performing quality assurance (QA) was difficult because you could not easily test individual components. Instead, developers had to simulate user input and then examine the resulting HTML output for an expected result. Different developers could not easily work on the same page at the same time.

ASP.NET

In 2002, Microsoft released ASP.NET, which allowed developers to use code-behind files to separate the HTML and the placement of server controls from the back-end code. This was a definite improvement for implementing SoC, but developers still created a single class for displaying output and responding to user input. This approach makes testing difficult because testing an individual page requires creating an instance of the page class, its child controls, and all dependent classes.

ASP.NET MVC

In 2009, Microsoft released ASP.NET MVC, which is named for the Model-View-Controller software architecture and provides three different layers of SoC:

Model. The data and behavior of the application

View. The user interface, which displays data provided by the model

Controller. Accepts user input, and calls the model and view to generate a response

Figure 1-1 shows the MVC design pattern and the communications between the layers.

Figure 1-1. The MVC design pattern

By providing SoC, MVC provides several benefits. Support for test-driven development allows QA personnel to query the model directly to verify that it provides an expected output when given a specific input. Developers can modify views to update the user interface without any potential impact on the business logic or data access layers. Controllers completely abstract requests from the models and views responding to the request, allowing web architects to specify a structure for the user interface without defining the application architecture.

Implementing SoC can increase development time for smaller applications, albeit by a small margin. However, SoC can dramatically reduce debugging, QA, and maintenance time. SoC also simplifies dividing development tasks between multiple developers. Therefore, the larger the development effort, the more important SoC becomes.

Planning for Long-Running Processes

Web users are impatient and will cancel a request or give up on a website entirely if pages do not load quickly. As a result, webpages typically need to be rendered in less than a second. That is enough time to query a database or a web service, but performing a longer-running task requires multiple requests.

Consider a travel agency web application that provides flight information from multiple airlines. If a user requests information about all flights between Boston and Chicago on a specific day, the web application might need to send web service requests to a dozen different airlines and wait for the responses before displaying the results to the user. One airline might respond in half a second, but another airline might take 10 seconds to respond.

If the web application queried each airline synchronously (in sequence, one after another), the response time would be delayed by the sum total of all the airline web services. It is more efficient to submit the web service queries asynchronously (in parallel, all at the same time). Then the response time is delayed only by the time required by the slowest web service.

When you create a method, such as a Button.Click event handler, the code in the method runs synchronously by default. In other words, the common language runtime (CLR) runs one line of code, waits for the results, and then moves on to the next line. This linear flow is easy for developers to understand, and it is efficient for short-running processes.

If you have long-running processes, such as waiting for a web service to respond, you can use asynchronous processing to allow the .NET Framework to perform other tasks instead of waiting for the response. When the asynchronous response is complete, you can retrieve the results and update the response to the user.

NOTE: WRITING ASYNCHRONOUS CODE

Ideally, any task that is not dependent on the results of other tasks should be performed asynchronously. Using asynchronous programming techniques improves performance and scalability. In practice, however, you need to weigh the benefits against the complexity of writing and maintaining asynchronous tasks.

Designing a Webpage for a Long-Running Process

Figure 1-2 shows the typical flow of a synchronous webpage. With this model, however, the user gets no feedback until the server finishes rendering the response. If it takes the server more than a few seconds, the user is likely to cancel the request.

Figure 1-2. The flow of a typical synchronous webpage

Figure 1-3 shows the typical flow of an asynchronous webpage. With this model, the server informs the user that the response will take a few moments. A client-side script regularly checks the server to determine whether the results are ready. When the long-running, asynchronous process has completed, the final results are displayed to the user.

You can run a long-running process while remaining responsive to users. In the travel agency example, developers might take one of these two approaches:

Display a loading page with a progress bar or other animation that shows the application is currently processing the request. This page uses JavaScript to communicate with the server. When the server reports that the results are ready, JavaScript loads the results page.

Immediately display a formatted results page. Instead of showing the results, a progress bar indicates that the results are loading. In the background, the page runs JavaScript to connect to the server and wait for results. As the server returns results (either partially or all at once), JavaScript adds the results to the page.

For processes that might take more than a minute or two to complete, gather the user’s email address and send her a notification with a link to retrieve the results.

Designing a Web Service for a Long-Running Process

Whereas web applications must render the HTML that the browser displays as the user interface, web services return raw data that the client application processes. Because the web service client creates the user interface, the web service developer does not need to decide how to communicate the delay to the user.

The web service developer does, however, need to design the web service to accommodate long-running asynchronous processes. If both the client and server are based on the .NET Framework, and the client is not protected by a firewall or Network Address Translation (NAT) device, you can use WSDualHttpBinding, netTcpBinding, NetNamedPipeBinding, NetPeerTcpBinding, or NetTcpContextBinding to create a callback contract on the client and then use that callback to notify the client that the process is complete.

NOTE: DUPLEX HTTP FOR SILVERLIGHT AND .NET CLIENTS

Silverlight clients can use PollingDuplexHttpBinding, which supports duplex communications and allows the client to be located behind a firewall or NAT device. Unfortunately, .NET 4.0 does not include a polling duplex HTTP binding. However, you can download a sample custom channel that might suit your needs at http://archive.msdn.microsoft.com/duplexhttp.

If the binding type does not support duplex communications, or you must communicate through a firewall that prevents incoming connections to the client, you should handle long-running web service requests by immediately providing a token the client can use to later retrieve the results. To provide better feedback to the end user, you can also provide an estimated wait time that the client can use to display the progress to the user. Then have the client regularly poll the server to determine if the process is complete.

Use polling to retrieve the results of a long-running query that is using a web service by following this process:

The client sends the request to the web service. This might be, for example, “List all flights between Boston and Chicago on May 1.”

The web service provides a unique token to the client and an approximate wait time. The token should be large and cryptographically random, such as a 20-byte value generated by RngCryptoServiceProvider. The wait time should be based on the actual wait time for similar requests.

The web service client displays a progress bar to the user to let him know the request is continuing and the application is responsive. The web service asynchronously calls a method to process the request and store the results in a database record associated with the token.

After an interval (for example, one-quarter of the estimated wait time), the web service client queries the web service for the results, providing the unique token. If the results are ready, the web service client formats and displays the data; otherwise, it repeats this step.

Objective Summary

Use client-side scripting to provide users with a rich, responsive interface. However, you must write server-side code when security is important. Additionally, server-side code is more efficient to write, test, troubleshoot, and maintain.

SoC simplifies development, testing, and updating of large-scale web applications. Strive to design applications with SoC dividing the functional layers of an application.

To perform a long-running request while appearing responsive to the user, divide a request into multiple steps. In the first step, launch the long-running process asynchronously and display a wait page to the user. Embed JavaScript in the wait page that queries the server for the status of the long-running process and retrieves the final results page when processing is complete.

Objective Review

Answer the following questions to test your knowledge of the information in this objective. You can find the answers to these questions and explanations of why each answer choice is correct or incorrect in the Answers section at the end of this chapter.

You are designing an ASP.NET web application that allows members of the Administrators role to edit content by using a HyperLink control on each page named EditHyperLink. You do not want nonadministrators to discover the location of the administration pages. Which approach should you recommend?

In the ASPX page, set the EditHyperLink.Visible property to True. In the JavaScript window.onload event handler, set the link’s style.display property to none if the user is not a member of the Administrators role.

In the ASPX page, set the EditHyperLink.Visible property to False. In the JavaScript window.onload event handler, set the link’s style.display property to block if the user is a member of the Administrators role.

In the ASPX page, set the EditHyperLink.Visible property to False. In the Page.Load event handler, set the HyperLink.Visible property to True if the user is a member of the Administrators role.

In the ASPX page, set the EditHyperLink.Visible property to False. In the EditHyperLink.Click event handler, set the HyperLink.Visible property to False if the user is not a member of the Administrators role.

You are designing an ASP.NET web application that provisions virtual machines for a testing environment. Users can provision from 1 to 10 virtual machines at a time, and each virtual machine provision might take up to 60 seconds. For security reasons, the server hosting the virtual machines allows provisioning requests only from the web server. You need to design the application to keep users notified of the provisioning progress. Which approach should you recommend?

On the server, start asynchronous processes to provision each virtual machine. On the client, use JavaScript to query the server every five seconds for a status update.

On the server, synchronously provision each virtual machine. When complete, return a status update to the user.

On the server, calculate the approximate total provisioning time. On the client, use JavaScript to connect to the server hosting the virtual machines and initiate the provisioning.

On the client, use JavaScript to launch a separate asynchronous process for each virtual machine to be provisioned. Within each process, request a page from the web server that provisions a virtual machine.

You are creating a new website for an enterprise organization. The enterprise has a quality assurance team that requires developers to use test-driven development. Additionally, the application architecture must partition according to the principle of SoC. Which template should you use?

Use the ASP.NET 4.0 web application project template.

Use the ASP.NET MVC 2 web application project template.

Use the Silverlight application project template.

Create an ASP.NET 4.0 website.

Thought Experiment: Moving a Site from an Intranet to the Internet

In the following thought experiment, you apply what you’ve learned about the “Plan the Division of Application Logic” objective to predict how a theoretical website architecture will perform. You can find answers to these questions in the Answers section at the end of this chapter.

You are a developer for City Power & Light. You are working with management to assess the impact of moving an intranet application to the Internet. The application was created using ASP.NET 2.0. Only authorized and authenticated employees located on the high-speed intranet are allowed to use the application. Employees can enter a customer’s identification number or street address, and then examine that customer’s power usage over time by viewing a list of monthly statistics or a graphical chart. Typically, employees interpret the information over the phone when a customer calls and requests information about his bill.

Because many of the employee computers have low-powered processors and outdated browsers, the application was designed without any JavaScript or client-side logic. Employees complain that during peak hours, it can take five or ten seconds to load a page with a chart. Showing charts for different time periods requires waiting for a new page to load.

Management needs to give customers direct access to their usage information. Answer the following questions about the future performance of the application:

Which factors currently limit the responsiveness of the site: client processing, server processing, client bandwidth, or server bandwidth? How could you improve the performance?

How will the website perform if the company provides customers access to it across the Internet without modifying the application?

How would you create a reasonably accurate estimate of the server processing capabilities and the amount of bandwidth the site might need on the Internet?

How would you reduce the amount of server processing time required to generate the charts?

How could you avoid reloading the entire webpage when changing the time period of a chart?

How would generating charts on the client affect the site’s performance? Which client-side technology would you use? How would you provide the raw data to the client?

How would using a content delivery network (CDN) reduce Internet bandwidth requirements? How might a CDN speed delivery of server-side or client-side charts?