Best practices: Designing Web ADF applications


Summary Designing Web applications with the Web Application Developer Framework (ADF) can be a complex process of balancing the integration of multiple data sources with rich and interactive functionality—all within the framework of a usable, well-performing, and aesthetic Web client interface. This topic contains recommendations for development, maintenance, and enhancement of your Web ADF application.

In this topic


Keep it simple

The best Web application is the one that people use. Follow the Web ADF developer paths to accomplish as much as possible using the Web ADF controls and application programming interfaces (APIs) before progressing to data source-specific capabilities.

AJAX

Asynchronous JavaScript and XML (AJAX) combines a number of existing Web technologies to enhance the user experience in a Web browser. It enables a Web application to communicate with other resources (for example, with Web servers) while you continue to interact with the application. While XML (Extensible Markup Language) is part of the acronym, it is often very slow to use. The Web ADF uses simple strings more efficiently. Evaluate your Web application to determine how best to leverage this technology as it is built into the Web ADF. Minimize callbacks or asynchronous requests made to your Web application.

Network and application capabilities and limitations

Maintaining adequate resources for your server products provides responsive Web sites and services. The topics and discussions that pertain to resources, scalability, and performance are broad and extensive. ESRI maintains a System Design Strategies document that provides information on many performance related issues and questions.
Since the Web ADF takes advantage of background, out-of-band calls via its AJAX implementation, increasing the capability of a client application to process these calls concurrently can improve performance. By default, the HTTP 1.1 specification defines a two connection limit for any client application (for example, a browser) to a remote Web server (the HTTP 1.0 specification is four connections). This means that all Hypertext Transfer Protocol (HTTP) communication with the remote server can only use two connections at a time. If six requests are made by the same application simultaneously, only two can be sent at a time, while the others remain in a queue.
On Windows platforms, this limit can be changed. The MaxConnectionsPerServer and MaxConnectionsPer1_0Server registry entries can be used to define the maximum number of HTTP connections by a client application to a remote Web server. For details on how to change this value, see the Microsoft Help and Support article WinInet limits connections per server. This change affects all Windows applications that use the HTTP protocol to connect to remote Web sites. While additional connections can be made, you are still subject to bandwidth limitations since all connections must share the same resources. However, in the scenario mentioned above, if the MaxConnectionsPerServer value is 6, all requests can be processed simultaneously via six separate connections. This often improves overall performance of the application when concurrent actions occur (for example, the application load).
IIS Web servers cannot explicitly limit the number of connections per client application, but they can limit the number of connections per Web site or Internet protocol (IP) address. Do not explicitly limit the number of connections to a Web site. Defining explicit limits on a Web site is only acceptable if the Web server resources cannot manage the number of connections above the limit.
Do not restricting connections based on an IP address either. Consider the scenario where multiple users access your Web site via a proxy server. The Web server considers all connections from the proxy server as coming from the same IP address. Anyone that uses the proxy server must share the number of connections, which may significantly limit the usability of your site.
A better option is to efficiently manage the connections made to your Web site. Reduce connection or session timeouts to save Web server resources and maintain maximum connectivity demanded by client applications. For example, by default, HTTP connections are persistent (or kept alive) for 120 seconds. If necessary, shorten the Web server connection timeout value to conserve connections, forcing the client to create new connections when needed. Techniques for managing IIS often vary for different versions and platforms. For information on IIS 6.0 on Windows Server 2003, see the Microsoft document Limiting Connections to Manage Resources.

Provide feedback at run time

When retrieving maps and queries from the server, it is helpful to provide users with feedback to let them know something is happening. Otherwise users may click repeatedly to retry the operation or give up on the application. You can provide feedback to users as the action is occurring. For example, the task framework in the Web ADF employs an executing-task animated Graphic Interchange Format (GIF) that tells the user that the task is being processed. You can use this same task framework for custom functionality in your application. If you develop your own custom functionality that performs work on the server before returning results to the user, provide some kind of image or progress indication to the user.
For more information on tasks, see the following topics:

Preserve user state

The Web is inherently stateless—each request is essentially a separate connection to the server. But Web applications need to provide continuity between requests. For example, mapping applications need to retain the user's map extent so that a zoom or pan retrieves the correct maps.
State can be preserved at one or more levels: on the client, at the Web application, or at the geographic information system (GIS) server. In the Web ADF at 9.3, most state information is preserved at the Web tier. The GIS server only preserves state when using non-pooled ArcGIS Server resources. 
You can also preserve state of the user's application between browsing sessions. For example, you can store information—such as the user's current map extent, visibility of floating windows, and selection graphics—in a database and restore those items to the Web page when the user logs into the site again. This kind of state preservation is not built into the Web ADF but can be accomplished through customization.

Separate presentation and implementation

Many organizations have separate staff for creating Web user interfaces and for executing business logic behind the scenes. Even if you design all aspects of your Web site, separating the interface from the implementation makes it easier to create and maintain your site in the long run.
ASP.NET allows you to separate presentation from implementation in a page by using the code-behind model. You can place controls for presenting results on the page, and use the code-behind file to execute logic. Visual Studio 2005 changed the default for new pages to not use code-behind files, but you have the option to use code-behind in the dialog for creating new pages. The Web Mapping Application template included with the Web ADF uses code-behind files for all .aspx pages.
You can take this separation a step further by creating components and using Web services for your business logic. These components and services can perform required tasks in the background and provide completed information for display by Web controls. You can also create custom Web controls to display information from back-end services.

Build components for reuse

If you build more than one Web Mapping Application, your sites will likely share some functionality. Rather than copying and pasting individual lines of code between applications, you will be more productive in the long run by developing components to share among applications.
Components range from simple to complex. As a start, you can create a function or method that accepts arguments and returns a result, and move code from your code page into the method. The code must be self-contained, with no references to global variables. Good candidates for componentization are functions that obtain a map, perform a query, or that perform some kind of utility function.
You can extend this approach by creating a class in a stand-alone file. This class might simply contain static methods that do not require creating an instance of the class. Or the class can have more complex functionality to manage mapping tasks. Such a class file can easily be copied between applications. The standard approach in ASP.NET 2.0 is to include application code class files in the App_Code folder in the Web site.
Finally, components can be packaged in a separate project and compiled to an independent .NET assembly and deployed as a .dll file. This allows easy sharing of the same component between applications. When changes need to be made in the code, they can be made once and redeployed among all applications using the code. The .NET components can be registered globally (in the Global Assembly Cache) so they are available to all applications from a central location.
For more information on creating components, see the Microsoft ASP.NET Web site.

Use embedded resources

ASP.NET 2.0 allows you to embed resources into .NET assemblies. For example, if you create a custom task that uses a graphic image, and you want to redistribute the task, you can embed the graphic into the dynamic-link library (DLL) so that you do not have to ship the graphic separately. You can also embed JavaScript and other types of resources and pages into the assembly.
To access these resources, use code to retrieve a uniform resource locator (URL) and insert it into the page. The client uses this URL to retrieve the resource. This URL uses the new WebResource.axd handler that can retrieve embedded resources. For details on embedding resources, see the Microsoft Help and Support article How to embed resources in ASP.NET 2.0 assemblies.

Create fail-safe Web ADF applications

The Web ADF follows a resource-centric model. Namely, a set of resource managers broker interaction between Web ADF controls and APIs. Each resource has a data source. Sometimes a data source is unavailable (for example, when the server is down). If one data source is unavailable, it should not cause the Web ADF application to fail. Existing data source implementations and controls support the fail-safe model. If you're developing a custom data source or control that utilizes a resource, you must account for a possible data source failure and use the following development patterns to implement a fail-safe architecture. (To account for failed resource creation in a resource manager control, use the Web application development pattern.)

Data source development pattern

  • Data source implementations fails on IGISDataSource.Initialize or IGISResource.Initialize if the resource is not available. The failure can be a false Initialized property or an exception on Initialize(). If this occurs, the resource manager control will do the following:
    1. Set GISResourceItem.Resource to null
    2. Set GISResourceItem.FailedToInitialize to true
    3. Set GISResourceItem.InitializationFailure to the message on the exception if any
This is done on every initialization (for example, on every callback).
  • For resources, use IGISResource.ValidationTimeout as the timeout for a validation. This property can be set using GISResourceManager.ValidationTimeout by the end user.
  • LoadState should not throw an exception.

Control development pattern

  • Controls check if a resource item is null or if GISResourceItem.Resource is null.
  • Controls should not call IGISResource.Initialize directly. Instead, they should call GISResourceItem.InitializeResource. This method checks for failure and sets appropriate properties.

Web application development pattern

If failed resources are present, GISResourceManager.FailureOnInitialize is true. If an application does not accept the expense of initializing a failed resource on every callback, it can set the resource item to null or remove it. You can do this in the ResourcesInit event for resource manager controls.