Chapter 21: Designing Web Applications
For more details of the topics covered in this guide, see Contents of the Guide.
- General Design Considerations
- Specific Design Issues
- Design Considerations for Layers
- Testing and Testability Considerations
- Technology Considerations
- Deployment Considerations
- Relevant Design Patterns
- Additional Resources
In this chapter, you will learn the general design considerations and key attributes for a Web application. This includes the guidelines for a layered structure; guidelines for performance, security, and deployment; and the key patterns and technology considerations.
A Web application is an application that can be accessed by the users through a Web browser or a specialized user agent. The browser creates HTTP requests for specific URLs that map to resources on a Web server. The server renders and returns HTML pages to the client, which the browser can display. The core of a Web application is its server-side logic. The application can contain several distinct layers. The typical example is a three-layered architecture comprised of presentation, business, and data layers. Figure 1 illustrates a typical Web application architecture with common components grouped by different areas of concern.
The typical structure of a Web application
The presentation layer usually includes UI and presentation logic components; the business layer usually includes business logic, business workflow and business entities components, and optionally a façade; and the data layer usually includes data access and service agent components. For more information about layered design, see Chapter 5, "Layered Application Guidelines." For more information about the components used in each layer, see Chapter 10 "Component Guidelines."
General Design Considerations
When designing a Web application, the goal of the software architect is to minimize the complexity by separating tasks into different areas of concern while designing a secure, high performance application. Follow these guidelines to ensure that your application meets your requirements, and performs efficiently in scenarios common to Web applications:
- Partition your application logically. Use layering to partition your application logically into presentation, business, and data access layers. This helps you to create maintainable code and allows you to monitor and optimize the performance of each layer separately. A clear logical separation also offers more choices for scaling your application.
- Use abstraction to implement loose coupling between layers. This can be accomplished by defining interface components, such as a façade with well known inputs and outputs that translates requests into a format understood by components within the layer. In addition, you can also use Interface types or abstract base classes to define a shared abstraction that interface components must implement.
- Understand how components will communicate with each other. This requires an understanding of the deployment scenarios your application must support. You must determine if communication across physical boundaries or process boundaries should be supported, or if all components will run within the same process.
- Consider caching to minimize server round trips. When designing a Web application, consider using techniques such as caching and output buffering to reduce round trips between the browser and the Web server, and between the Web server and downstream servers. A well designed caching strategy is probably the single most important performance related design consideration. ASP.NET caching features include output caching, partial page caching, and the Cache API. Design your application to take advantage of these features.
- Consider logging and instrumentation. You should audit and log activities across the layers and tiers of your application. These logs can be used to detect suspicious activity, which frequently provides early indications of an attack on the system. Keep in mind that it can be difficult to log problems that occur with script code running in the browser.
- Consider authenticating users across trust boundaries. You should design your application to authenticate users whenever they cross a trust boundary; for example, when accessing a remote business layer from the presentation layer.
- Do not pass sensitive data in plaintext across the network. Whenever you must pass sensitive data such as a password or authentication cookie across the network, consider encrypting and signing the data or using Secure Sockets Layer (SSL) encryption.
- Design your Web application to run using a least-privileged account. If an attacker manages to take control of a process, the process identity should have restricted access to the file system and other system resources in order to limit the possible damage.
For more information on general design considerations, see Chapter 17 "Crosscutting Concerns."
Specific Design Issues
You must consider several common issues as you develop your design. These issues can be categorized into specific areas of the design. The following sections provide guidelines to help you avoid the common issues in each area:
- Application Request Processing
- Exception Management
- Logging and Instrumentation
- Page Layout
- Page Rendering
- Session Management
Application Request Processing
At a high level, a Web application can perform request processing in two ways. With the post back approach, the browser primarily communicates with the server using Web Forms post backs. A popular alternative approach is to use RESTful service calls between the browser and the server. These two approaches each have advantages and disadvantages, and your choice may impact how you address the design issues described below.
When choosing a request processing strategy, you should consider how much control you require over the UI in your application, your development and testing approach, and your performance and scaling requirements.
The post back approach typically allows a forms-based development experience, and uses rich server-side controls that render the corresponding HTML, associated view state, and interaction logic to the browser. Consider this approach if you developing a forms-based Web application and require a rapid application development (RAD) experience.
The REST-full approach typically allows finer-grained control over the UI of your application, and provides more flexibility in terms of navigation, testability, and separation of concerns. Consider using this approach if your application requires flexible navigation, fine control over its UI, may use alternate UI rendering technologies, or if you are using a test-driven development approach.
Regardless of the request processing strategy you choose, you should ensure separation of concerns by implementing the request processing logic and application logic separately from the UI. Several patterns help achieve this. In general, the Model-View-Presenter (MVP) or similar patterns can be used in a Web Forms post back approach to help provide a clean separation of concerns. The Model-View-Controller (MVC) pattern is typically used in a REST-full request processing approach.
Also consider the following guidelines when designing a request processing strategy:
- Consider centralizing the common preprocessing and post processing steps of Web page requests to promote logic reuse across pages. For example, consider creating an HTTP module, or a base class derived from the ASP.NET Page class, to contain your common preprocessing and post processing logic.
- Choose an appropriate approach or pattern for your UI processing. Consider dividing UI processing into three distinct roles—model, view, and controller/presenter—by using MVC, MVP, or similar patterns. Avoid mixing processing and rendering logic in your components.
- If you are designing views for handling large amounts of data, consider giving the view access to the model by using the Supervising Presenter (or Supervising Controller) pattern, which is a form of the MVP pattern. If your application does not have a dependency on view state and you have a limited number of control events, consider using the MVC pattern.
- Consider using the Intercepting Filter pattern to implement the processing steps as pluggable filters when appropriate.
- Ensure that you protect all sensitive data sent over the network, especially over the Internet. Use secure channel protocols such as SSL, and consider encrypting and digitally signing all highly sensitive data sent over both internal and external networks.
Designing an effective authentication strategy is important for the security and reliability of your application. Improper or weak authentication can leave your application vulnerable to spoofing attacks, dictionary attacks, session hijacking, and other types of attack. Consider the following guidelines when designing an authentication strategy:
- Identify trust boundaries within Web application layers. This will help you to determine where to authenticate users.
- Enforce secure account management practices such as account lockouts and password expirations, and strong password policies that specify the minimum password length and complexity.
- Use a platform- supported authentication mechanism such as Windows Authentication when possible. Where you decide to use Forms Authentication, take advantage of the built-in support in ASP.NET instead of designing a custom authentication mechanism. Consider using a federated service or single sign on (SSO) if you want to allow users to log on to several sites with a single set of credentials.
- When you must store passwords in a database, do not store them as plaintext; instead, store a hash (or salted hash) of the password.
Authorization determines the tasks that an authenticated identity can perform, and identifies the resources that can be accessed. Designing an effective authorization strategy is important for the security and reliability of your application. Improper or weak authorization leads to information disclosure, data tampering, and elevation of privileges. Defense in depth is the key security principle to apply to your application's authorization strategy. Consider the following guidelines when designing an authorization strategy:
- Authorize users as they cross all trust boundaries. Use URL authorization for page and directory access control. Access downstream resources using a trusted identity based on the trusted subsystem model as described in Chapter 19 "Physical Tiers and Deployment."
- Consider the granularity of your authorization settings. Building your authorization with too much granularity will increase your management overhead; however, using less granularity may reduce flexibility.
- Use impersonation and delegation to take advantage of the user-specific auditing and granular access controls of the platform, but consider the effect on performance and scalability.
Caching improves the performance and responsiveness of your application. However, incorrect caching choices and poor caching design can degrade performance and responsiveness. You should use caching to optimize reference data lookups, avoid network round trips, and avoid unnecessary and duplicate processing. To implement caching, you must first decide when to load data into the cache. Try to load cache data asynchronously or by using a batch process to avoid client delays. Consider the following guidelines when designing caching:
- Cache data in a ready to use format when possible, and avoid caching volatile data that changes regularly. Avoid caching sensitive information unless it is encrypted.
- Use output caching to cache pages that are relatively static. This dramatically improves performance, while still supporting variation based on submitted values. If only parts of the page are relatively static, consider using partial page caching with user controls.
- Pool shared resources that are expensive, such as network connections, instead of caching them.
For more information on caching, see Chapter 17 "Crosscutting Concerns."
Designing an effective exception management strategy is important for the security and reliability of your application. Correct exception handling in your Web pages prevents sensitive exception details from being revealed to the user, improves application robustness, and helps to avoid leaving your application in an inconsistent state in the event of an error. Consider the following guidelines when designing an exception management strategy:
- Provide user friendly error messages to notify users of errors in the application, but ensure that you avoid exposing sensitive data in error pages, error messages, log files, and audit files.
- Ensure that you catch unhandled exceptions, and clean up resources and state when an exception occurs. Design a global exception handler that displays a global error page or an error message for all unhandled exceptions. Avoid the use of custom exceptions when not necessary.
- Do not catch exceptions unless you must handle them; for example, to remove sensitive information or add additional information to the exception. Do not use exceptions to control application logic flow.
For more information on exception management, see Chapter 17 "Crosscutting Concerns."
Logging and Instrumentation
Designing an effective logging and instrumentation strategy is important for the security and reliability of your application. You should audit and log activity across the tiers of your application. These logs can be used to detect suspicious activity, which frequently provides early indications of an attack on the system, and can help to address repudiation threats where users deny their actions. Log and audit files may be required in legal proceedings to prove the wrongdoing of individuals. Auditing is generally considered to be most authoritative if the audit is generated at the precise time of resource access, and by the routine that accesses the resource. Consider the following guidelines when designing a logging and instrumentation strategy:
- Consider auditing in all layers of the application for user management events, system critical events, business critical operations, and unusual activities.
- Create secure log file management policies such as restricting access to log files, and allowing only write access to users. Ensure that your logging and instrumentation mechanisms are configurable during deployment and when in production.
- Do not store sensitive information in log or audit files.
Design your navigation strategy in a way that separates it from the processing logic. Your strategy should allow users to navigate easily through your screens or pages. Designing a consistent navigation structure for your application will help to minimize user confusion as well as reduce the apparent complexity of the application. Consider the following guidelines when designing your navigation strategy:
- If you are using a Web Forms post back approach, consider using design patterns such as MVP to decouple UI processing from output rendering. Avoid mixing navigation logic with your user interface components by handling navigation in the Presenter.
- If you are using a REST-full approach, consider using a MVC pattern to decouple application logic, data, and navigation into separate components. Typical MVC application implementation provide flexible navigation support by directing requests to a controller component that then coordinates the application's UI and data.
- Consider encapsulating navigation in a master page so that it is consistent throughout the application. However, avoid hard coding navigation paths in your application. Also, ensure that users can only navigate to views for which they are authorized.
- Consider using a site map to help users find pages on the site, and to allow search engines to crawl the site if appropriate. Consider using visual elements such as embedded links, navigation menus, and breadcrumb navigation in the UI to help users understand where they are, what is available on the site, and how to navigate the site quickly. Consider using wizards to implement navigation between forms in a predictable way.
Design your application so that the page layout can be separated from the specific UI components and UI processing. When choosing a layout strategy, consider whether designers or developers will be building the layout. If designers will be building the layout, choose a layout approach that does not require coding or the use of development-focused tools. Consider the following guidelines when designing your layout strategy:
- Use Cascading Style Sheets (CSS) for layout whenever possible, rather than table-based layout. However, use table-based layout when you must support a grid layout or where the data is represented as a table. Bear in mind that table-based layout can be slow to render, and there may be issues with complex layout.
- Use a common layout for pages where possible to maximize accessibility and ease of use. Avoid designing and developing large pages that accomplish multiple tasks, particularly where only a few tasks are usually executed with each request. Minimize page size where possible to maximize performance and reduce bandwidth requirements.
- Use master pages in ASP.NET applications to provide a common appearance and behavior for all of the pages, and to allow updates to the site with minimum effort. Consider extracting common sections of pages into separate user controls to reduce the overall complexity and allow reuse of these controls.
- Consider using the ASP.NET AJAX server controls and the ASP.NET AJAX client-side library to make client script more easily portable between different browsers. Also, avoid mixing client-side script with HTML code. Doing so makes the page more complex and harder to maintain. Place client side script in separate script files so they can be cached by the browser.
- When migrating an existing Web application, consider using Silverlight controls in ASP.NET pages to provide a rich user experience and minimize application reengineering.
When designing for page rendering, you must ensure that you render the pages efficiently and maximize interface usability. Consider the following guidelines when designing a page-rendering strategy:
- Consider using client-side script or ASP.NET AJAX for an improved user experience and better responsiveness by reducing the number of post backs required. Using custom client-side script can make applications harder to test because script support varies between different browsers and versions. Instead, consider using ASP.NET AJAX, which supports most common browsers. Remember that the use of client-side code of any type (including script emitted by the built-in ASP.NET controls) can affect accessibility. Ensure that you provide appropriate accessibility support for specialist user agents and disabled users.
- Consider data-binding options. For example, you can bind collections, DataReader objects, DataSet tables, and custom objects to many ASP.NET controls. Use data-paging techniques to minimize scalability issues associated with large amounts of data, and to improve performance and response times.
- Consider designing to support localization in UI components.
- Abstract the user process components from data rendering and acquisition functions.
When designing a Web application, an efficient and secure session management strategy is important for performance and reliability. You must consider session management factors such as what to store, where to store it, and how long information will be kept. Consider the following guidelines when designing a session management strategy:
- Consider if you actually do need to store session state. Using session state adds overhead to each page request.
- Ensure that you persist session data when required, but consider using read-only sessions or disabling session state altogether to improve performance where this is appropriate.
- If you have a single Web server, require optimum session state performance, and have a relatively limited number of concurrent sessions, use the in-process state store. However, if your session data is expensive to recreate, and you require durability in the event of an ASP.NET restart, use the session state service running on the local Web server. For multiple server (Web farm) scenarios, where you must centralize session data storage across servers, consider using the SQL Server state store.
- If you are storing state on a separate server, protect your session state communication channel using techniques such as SSL or IPSec.
- Prefer basic types for session data to reduce serialization costs.
Designing an effective validation solution is important for the security and reliability of your application. Improper or weak validation can leave your application vulnerable to cross-site scripting attacks, SQL injection attacks, buffer overflows, and other types of input attack. Consider the following guidelines when designing a validation strategy:
- Validate all data crossing the trust boundaries of your application. Assume that all client controlled data is malicious and must be validated.
- Design your validation strategy to constrain, reject, and sanitize malicious input; and validate all input data based on length, range, format, and type.
- Use client-side validation for optimum user experience and reduced network round trips, but always validate on the server for security reasons.
- Investigate third-party solutions, design patterns, and libraries that can help you to centrally manage and reuse validation rules and code.
For more information on validation techniques, see Chapter 17 "Crosscutting Concerns."
Design Considerations for Layers
If you have chosen to use a layered design for your application, consider the specific issues for each layer described in the following sections.
The presentation layer of your Web application displays the UI and facilitates user interaction. The design should focus on separation of concerns, where the user interaction logic is decoupled from the UI components. You should consider using separate UI components and presentation logic components in complex interfaces, and base your UI components on standard Web controls where possible. You can compile the controls into an assembly for reuse across applications, or if you need to add additional features to existing server controls.
For Web applications, the presentation layer consists of a server-side component (which renders the HTML) and a client-side component (the browser or user agent that executes scripts and displays the HTML). Usually, all presentation logic exists in the server components, and the client components only display the HTML. With client-side techniques such as AJAX, it is possible to execute logic on the client, usually to improve the user experience. Doing so requires extra development effort and testing. If you decide to do any validation on the client, ensure that you repeat the validation on the server, as any client side validation can easily be circumvented.
When designing the business layer for your Web application, consider how to implement the business logic and long-running workflows. Using a separate business layer that implements the business logic and workflows can improve the maintainability and testability of your application, and allow you to centralize and reuse common business logic functions. Consider designing business entities that represent the real world data, and use these to pass data between components.
Design your business layer to be stateless, which helps to reduce resource contention and increase performance, and consider using a message-based interface. This works well with a stateless Web application business layer. If you perform business critical operations in your business layer, design to use transactions to maintain integrity and prevent data loss.
Consider designing a data layer for your Web application that abstracts the logic necessary to access the database. Using a separate data layer makes the application easier to configure and maintain, and hides the details of the database from other layers of the application. Design entity objects that the data layer can populate or use to update the data source, and use data transfer objects (DTOs) when interacting with other layers and to pass the data between layers.
Design the data layer to take advantage of connection pooling to minimize the number of open connections, and consider using batch operations to reduce round trips to the database. The data layer may also need to access external services using service agents. Also, ensure that you design an exception handling strategy to handle data access errors, and to propagate exceptions to the business layer.
Consider designing a separate service layer if you plan to deploy your business layer on a remote tier, or if you plan to expose your business logic using a Web service. Design the services to achieve maximum reusability by not assuming the specific details of clients that will use them, and avoid changes over time that might break the service interface for existing clients. Instead, implement versions of the interface to allow clients to connect to the appropriate version.
If your business layer resides on a remote tier, design coarse-grained service methods in order to minimize the number of round trips, and to provide loose coupling. Also, design the services to be idempotent (so that they can manage the situation where the same request message arrives more than once) and commutative (so that they can manage the situation where messages that perform a specific set of task steps arrive in the wrong order). Ensure that you do not implement business rules in a service interface, which can make is more difficult to keep the interface stable and may generate unnecessary dependencies across components and clients.
Finally, consider interoperability requirements by choosing appropriate protocols and transport mechanisms. For example, use ASMX for broad reach and WCF for more fine control over configuration. Decide whether the interface will expose SOAP, REST, or both methods. For more information about exposing services, see Chapter 9 "Service Layer Guidelines" and Chapter 18 "Communication and Messaging."
Testing and Testability Considerations
Testability is a measure of how well your system or components allow you to create test criteria and execute tests to determine if the criteria are met. You should consider testability when designing your architecture because it makes it easier to diagnose problems earlier and reduces maintenance cost. Consider the following guidelines for testability:
- Clearly define the inputs and outputs of the application's layers and components during the design phase.
- Consider separated presentation patterns, such as MVC or MVP in the presentation layer. This allows the presentation logic to be unit tested.
- Design a separate business layer to implement the business logic and workflows, which improves the testability of your application.
- Design loosely coupled components that can be tested individually.
- Design an effective logging and tracing strategy, which allows you to detect or troubleshoot errors that might otherwise be difficult to find. Provide logging and tracing information that can be consumed by monitoring or management tools. This will help you to locate and focus on the faulty code when errors occur. Log files should contain information that can be used to replicate the issue.
On the Microsoft platform, from an ASP.NET standpoint, you can combine the ASP.NET Web Forms model with a range of other technologies, including ASP.NET AJAX, ASP.NET MVC, Silverlight, and ASP.NET Dynamic Data. Consider the following guidelines:
- If you want to build applications that are accessed through a Web browser or specialized user agent, consider using ASP.NET.
- If you want to build applications that provide increased interactivity and background processing, with fewer page reloads, consider using ASP.NET with AJAX.
- If you want to build applications that include rich media content and interactivity, consider using ASP.NET with Silverlight controls.
- If you are using ASP.NET, consider using master pages to implement a consistent UI across all pages.
- If you are building a data driven Web application with pages based on the data model of the underlying database, consider using ASP.NET Dynamic Data.
- If you are using a test-driven development approach, or need fine-grained control over your UI, consider using the MVC pattern and ASP.NET MVC to cleanly separate application and navigation logic from your application's UI.
When deploying a Web application, you should take into account how layer and component location will affect the performance, scalability, and security of the application. You might also need to consider design tradeoffs. Use either a distributed or a nondistributed deployment approach, depending on the business requirements and infrastructure constraints. Nondistributed deployment will generally maximize performance by reducing the number of calls that must cross physical boundaries. However, distributed deployment will allow you to achieve better scalability and allows each layer to be secured separately.
In a nondistributed deployment scenario, all the logically separate layers of the Web application are physically located on the same Web server, except for the database. You must consider how the application will handle multiple concurrent users, and how to secure the layers that reside on the same server. Figure 2 shows this scenario.
Nondistributed deployment of a Web application
Consider the following guidelines when choosing a nondistributed deployment:
- Use nondistributed deployment if your Web application is performance sensitive, because the local calls to other layers reduce the impact on performance that would be caused by remote calls across tiers.
- If you do not need to share the business logic with other applications, and only the presentation layer will access it, design a component-based interface for your business layer.
- If your business logic and presentation logic run in the same process, avoid authentication at the business layer.
- Use a trusted identity (through the trusted subsystem model) to access the database. This improves the performance and scalability of your application.
- Decide how you will protect sensitive data passed between the Web server and the database server.
In a distributed deployment scenario, the presentation and business layers of the Web application reside on separate physical tiers, and communicate remotely. You will typically locate your business and data access layers on the same sever. Figure 3 shows this scenario.
Distributed deployment of a Web application
Consider the following guidelines when choosing a distributed deployment:
- Do not deploy your business layer on separate tier unless it is necessary; for example, to maximize scalability, or when security concerns prohibit you from deploying your business logic on your front-end Web server.
- Consider using a message-based interface for your business layer.
- Consider using the TCP protocol with binary encoding to communicate with the business layer for best performance.
- Consider protecting sensitive data passed between different physical tiers.
When you deploy your Web application on multiple servers, you can use load balancing to distribute requests so that they are handled by different Web servers. This helps to maximize response times, resource utilization, and throughput. Figure 4 shows this scenario.
Load balancing a Web application
Consider the following guidelines when designing your Web application to use load balancing:
- Avoid server affinity when designing Web applications if possible because this can negatively affect the application's ability to scale out. Server affinity occurs when all requests from a particular client must be handled by the same server. It usually occurs when you use locally updatable caches, or in-process or local session state stores. If you must support server affinity, configure the cluster to route all requests from the same user to the same server.
- Consider designing stateless components for your Web application; for example, a Web front end that has no in-process state and no stateful business components. If you must store state for users, avoid the use of in-process session management in a Web farm unless you can configure affinity and guarantee that requests from the same user will be routed to the same server. Instead, use of an out-of-process state server service or a database server.
- Consider using Windows Network Load Balancing (NLB) as a software solution to implement redirection of requests to the servers in an application farm.
- Consider using clustering to minimize the impact of hardware failures.
- Consider partitioning your database across multiple database servers if your application has high input/output requirements.
For more information on deployment patterns, see Chapter 19 "Physical Tiers and Deployment."
Relevant Design Patterns
Key patterns are organized into categories such as Caching, Exception Management, Logging and Instrumentation, Page Layout, Presentation, Request Processing, and Service Interface Layer; as shown in the following table. Consider using these patterns when making design decisions for each category.
Cache Dependency. Use external information to determine the state of data stored in a cache.
Page Cache. Improve the response time for dynamic Web pages that are accessed frequently but change less often and consume a large amount of system resources to construct.
Exception Shielding. Filter exception data that should not be exposed to external systems or users.
Logging and Instrumentation
Provider. Implement a component that exposes an API that is different from the client API, to allow any custom implementation to be seamlessly plugged in.
Page Layout (UI)
Composite View. Combine individual views into a composite representation.
Template View. Implement a common template view, and derive or construct views using this template view.
Transform View. Transform the data passed to the presentation tier into HTML to be displayed on the UI.
Two-Step View. Transform the model data into a logical presentation without any specific formatting, and then convert that logical presentation into the actual formatting required.
Model-View-Controller. Separate the data in the domain, the presentation, and the actions based on user input into three separate classes. The Model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the View), and responds to instructions to change state (usually from the Controller). The View manages the display of information. The Controller interprets the mouse and keyboard inputs from the user, informing the model and/or the view to change as appropriate.
Model-View-Presenter. Separate request processing into three roles, with the View being responsible for handling user input, the Model responsible for application data and business logic, and the Presenter responsible for presentation logic and for coordinating the interaction between the View and the Model.
Passive View. A variant of the MVC pattern. Reduce the view to the absolute minimum by allowing the controller to process user input and maintain the responsibility for updating the view.
Supervising Presenter (or Supervising Controller). A variation of the MVC pattern in which the controller handles complex logic, in particular coordinating between views, but where the view is responsible for simple view specific logic.
Intercepting Filter. Create a chain of composable filters (independent modules) to implement common preprocessing and post processing tasks during a Web page request.
Page Controller. Accept input from the request and handle it for a specific page or action on a Web site.
Front Controller. Consolidate request handling by channeling all requests through a single handler object, which can be modified at run time with decorators.
Service Interface Layer
Façade. Implement a unified interface to a set of operations to provide a simplified, reduced coupling between systems.
Service Interface. A programmatic interface that other systems can use to interact with the service.
For more information on the Page Cache pattern, see "Enterprise Solution Patterns Using Microsoft .NET" at http://msdn.microsoft.com/en-us/library/ms998469.aspx.
For more information on the Model-View-Controller (MVC), Page Controller, Front Controller, Template View, Transform View, and Two-Step View patterns, see Fowler, Martin. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002. Or at http://martinfowler.com/eaaCatalog/.
For more information on the Composite View, Supervising Presenter, and Presentation Model patterns, see "Patterns in the Composite Application Library" at http://msdn.microsoft.com/en-us/library/cc707841.aspx.
For more information on the Exception Shielding pattern, see "Useful Patterns for Services" at http://msdn.microsoft.com/en-us/library/cc304800.aspx.
For more information on the Service Interface pattern, see "Service Interface" at http://msdn.microsoft.com/en-us/library/ms998421.aspx.
For more information on the Provider pattern, see "Provider Model Design Pattern and Specification, Part I" at http://msdn.microsoft.com/en-us/library/ms998421.aspx.
The following resources will be useful when designing Web applications:
- For more information on designing and implementing Web client applications, see "Design and Implementation Guidelines for Web Clients" at http://msdn.microsoft.com/en-us/library/ms978605.aspx.
- For more information on designing distributed Web applications, see "Designing Distributed Applications" at http://msdn.microsoft.com/en-us/library/aa292470(VS.71).aspx.
- For more information on Web application performance issues, see "Improving .NET Application Performance and Scalability" at http://msdn.microsoft.com/en-us/library/ms998530.aspx.
- For more information on Web application security, see "Improving Web Application Security: Threats and Countermeasures" at http://msdn.microsoft.com/en-us/library/ms994921.aspx.