Adapter Mappings

An adapter defines a specific set of characteristics for a particular requesting device. Suppose you are an OEM designing a new device based on a Palm Pilot, and you want to make hardware modifications and enhancements. To develop an ASP.NET mobile Web Forms application for your new device, you require a customized device adapter to make full use of the enhanced hardware feature set.

Inside the Web.config file, you map each of your mobile controls to the customized adapter that you created for it. Not only can you specify individual device adapter sets for device-specific customization, but also you can further customize by inheriting one device adapter set from another, thus customizing behavior for specific device/control combinations.

Inside Web.config

To map mobile controls and device adapters, declaratively configure them in the <mobileControls> section of the <system.web> element. You can do so in the Web.config file for changes to be isolated to the given application, or in the machine.config file for changes to the entire computer. Computer-wide settings are located in the machine.config file for the .NET Framework installation under %WINDIR% (your Microsoft Windows directory). Here, you can specify the individual adapter sets that are chosen at run time.

Note   If a <mobileControls> section does not currently exist in your Web.config file, you can add one anywhere among other sections within the <system.web> element.

A typical Web.config file contains a <configuration> section, which in turn contains the following sections:

  • <system.web>. Sets compilation information for debugging and custom error messages. Also sets the authentication mode, application level trace logging, session state settings, file download permissions, and application level globalization. In addition, this file specifies device filters.
  • <appSettings>. Specifies configurations for user application property settings.

Declaring an Adapter Set

A device adapter set is essentially the mapping mechanism within the web.config file. For each control that uses a customized device adapter, you must include the following information within the device adapter set: a predicate class, a predicate method, a page adapter, and the control's name and associated device adapter.

To add a device adapter set to the Web.config file of your application, you must declare a device adapter set by using a <device> element in the <mobileControls> section of the Web.config file, as shown in the following example.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
   <system.web>
      <!-- Other settings previously specified reside here. -->
      <mobileControls>
         <device name="myDeviceAdapter"
            predicateClass="fullyQualifiedAdapterClass"
            predicateMethod="specificMethodToInvoke"
            pageAdapter="fullyQualifiedPageAdapter">

            <control name="fullyQualifiedControl"
               adapter="fullyQualifiedPageAdapter"/>

            <!-- Add additional control names here. -->

         </device>
      </mobileControls>
   </system.web>
</configuration>

Defining Device Attributes

As shown in the previous code, you must include the following attributes in each adapter set:

  • name
    This attribute uniquely identifies the device adapter set.
  • inheritsFrom
    This optional attribute indicates that the current device adapter set inherits from another set, which is identified by its specified name. The parent device adapter set can reside anywhere in the same <mobileControls> section of the same Web.config file or it can reside in a parent Web.config file.
  • predicateClass and predicateMethod
    These attributes point to a static method that is called to evaluate whether the adapter set is appropriate for the current device. The method takes a single parameter of type HttpContext, and returns a Boolean value indicating whether the adapter set is applicable. The method can examine capabilities of the target device using the Browser property of the provided HttpContext object, which returns a MobileCapabilities object.
  • pageAdapter
    Identifies the page adapter class for the device set, a type that implements the IPageAdapter interface.

If a <device> section includes the inheritsFrom attribute, you do not need to declare the predicateClass, predicateMethod, or pageAdapter attributes. Instead, your device adapter set can inherit these from the parent device adapter set definition.

Note   Although these attributes are not necessary, you can define them if it is appropriate for your application.

You can place any number of <control> sections or elements within an adapter set — with each providing a specific control adapter mapping (a class that implements IControlAdapter). A <control> element has two attributes: a name attribute that specifies the class of the control to be mapped, and an adapter attribute that specifies the class of the control adapter.

Mapping Considerations

Although there is a one-to-one mapping between control and adapter, it is not necessary to write a unique control adapter class for every control/device combination. In general, if a new mobile control uses inheritance or simple composition, and does not require customized output, it does not require a control adapter. Consider the following alternatives:

  • An adapter or set of adapters might apply to a general type of device. For example, all HTML 3.2 devices might have the same set of device adapters. However, for some controls, there might be more specialized device adapters for more specific devices; for example, you might want to write a Calendar control device adapter that is specialized for the Pocket PC.
  • A control adapter might be associated with a control base class, rather than with individual controls. For example, a single adapter might be sufficient to render all validator controls inheriting from the BaseValidator class.
  • It is even possible to write fully functional mobile controls that do not use device adapters. However, it is strongly recommended that developers write device adapters where appropriate, because much of the flexibility of the architecture is lost if any single control on the page does not use device adapters.
  • New controls created by extending existing controls — user controls, composite controls, and controls that created through inheritance and that contain existing controls — do not need device adapters, because the adapters of the contained controls are used.

Understanding the Device Adapter Selection Process

The following process describes how a device adapter set for a page is chosen:

  1. ASP.NET iterates through the collection of device adapter sets, as defined by <device> sections in Web.config. The Web.config file closest to the requested page is iterated first, then each successive Web.config file higher in the configuration hierarchy; the Machine.config file is iterated last.
  2. The associated predicate for each device adapter set is evaluated by using the predicateClass and predicateMethod attributes.
  3. Each predicate uses the provided HttpContext object to examine the device capabilities of the target device, and returns true or false, indicating whether the device adapter sets are applicable.
  4. As soon as any predicate returns true, that device adapter set is considered chosen. At this point, the system uses the pageAdapter attribute of the <device> element to determine which class to create an instance of and to create the adapter.
  5. If none of the predicates in Web.config return true, the process is repeated for the device adapter sets in the parent directory's Web.config file.

For each control, the page is called to provide a device adapter for the specified control type. ASP.NET uses the following steps to choose the appropriate control adapter:

  1. The device adapter set used is the same one chosen for the page's device adapter.

  2. If the device adapter set contains a <control> element that directly maps the control class to a device adapter class, an instance of the specified adapter class is created.

  3. If the device adapter set cannot be directly mapped, a new instance of the base class for the control is created.

    This process is repeated until the base class Control is reached.

    If, at any time, a direct mapping is found, a new instance of the specified device adapter class is created.

  4. If a mapping has still not been found, and the device adapter set inherits from another adapter set, the steps for adapter selection are repeated for the parent adapter set. This continues up the hierarchy of adapter sets until a mapping is found.

The results of the lookup are cached, so the specified lookup only needs to be performed for the first relevant control once. The behavior described above is preserved.