Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] - نسخه متنی

Andy Wigley; Peter Roxburgh

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید






Configuring Device Adapters


Device adapters provide the device-specific implementation of a mobile control, as Chapter 22, you'll learn how to write device adapter code for custom controls and how to add them to existing device adapter sets. In this section, you'll review the role of device adapters, discover how the runtime selects a device adapter set for the requesting device, and learn how to extend an existing device adapter set to add support for custom device adapters that support new devices or new markup languages.


Figure 19-5: Several device adapters mapping to a single mobile control


The Role of Device Adapters


After the runtime successfully identifies a device and populates the MobileCapabilities object for a request, it must render the most appropriate markup for the device. By now, you're familiar with the idea that mobile controls are abstract—in other words, their physical appearance on the page isn't fixed across all devices. For example, a Command control can appear as a textual hyperlink on one device, while on another it maps to a softkey.

Device adapter classes are the counterparts of mobile control classes that implement the rendering of a mobile control on a given device. Think of device adapter classes as the bridge between an abstract control and a client. Figure 19-6 illustrates the relationship between the client, control, and adapter. Notice that for any given client request, the control has a unique adapter. Also, each new instance of a control binds to a new instance of that control's adapter.


Figure 19-6: The relationship between client, control, and adapter

When creating the output that a client displays, the device adapter class generates content optimized for the requesting device by tailoring it based on the properties of the MobileCapabilities object for the current request. For example, the device adapter class for the TextBox mobile control outputs markup for a text box that is rendered consistently on different WML browsers by checking the RendersBreaksAfterWMLInput property. If the device automatically renders a break (RendersBreaksAfterWMLInput is true), the MobilePage and the TextBox device adapters create markup that consists solely of an <input> element. If the device doesn't insert a break, these classes ensure that the rendered markup contains both an <input> element and a <br/> element. Because the device adapter classes determine the device capabilities from the MobileCapabilities object, changes in the <browserCaps> configuration settings for a given client type can result in changes in how information is displayed on that client.

ASP.NET Mobile Controls supports a broad family of WML 1.1, WML 1.2, cHTML 1.0, HTML 3.2, and XHTML clients. The existing device adapters yield good results on most handheld devices available at the time of this writing. Microsoft included the device adapter sources in the Mobile Internet Toolkit release to encourage extensibility and to prompt developers to create device adapters for use with current and future mobile devices. With the release of ASP.NET Mobile Controls, which supersedes the Microsoft Mobile Internet Toolkit, device adapter sources are no longer shipped with the product, but instead are available for separate download. Go to Chapter 22.


Using Device Adapter Sets


You define, or map, the relationship between device adapters and mobile Web Forms controls in either Web.config or machine.config. More specifically, you group together control adapters, and these groups form named device adapter sets. For example, the ASP.NET mobile controls come presupplied with three types of device adapter sets, which are defined as elements of the machine.config file: <HtmlDeviceAdapters>, <WmlDeviceAdapters>, and <ChtmlDeviceAdapters>, and Device Update 2 adds support for <XHTMLDeviceAdapters>.

Each device adapter set maps each mobile control to an appropriate device adapter, which renders the correct markup for a client. When the runtime receives a client request, it assigns one of the device adapter sets to that request, thus defining which control–device adapter pairings will service the request.

You define device adapter sets within a <mobileControls> element in either the Web.config file or the machine.config file. The <mobileControls> element supports multiple child <device> elements, which you use to declare device adapter sets. Table 19-3 shows the five attributes that the <device> element supports.



























Table 19-3: Attributes of the <device> Element


Attribute


Description


name


The name of the device adapter set.


predicateClass


The name of the class containing the predicate method. (See next table entry.)


predicateMethod


The name of the adapter set's predicate method. The predicate method is a static method that the runtime uses to ascertain whether the device adapter set is suitable for the current client device.


pageAdapter


The name of the page adapter class that corresponds to the device adapter set.


inheritsFrom


An optional attribute that you can use to inherit configuration settings from another device adapter set. You'll learn more about device adapter set inheritance later in the section "Device Adapter Set Inheritance."


The <device> element supports multiple child <control> elements, which you use to map specific control adapters to mobile controls. For example, you can map a WMLPanelAdapter control adapter to the mobile Web Forms Panel control. The <control> element has two attributes: name and adapter. You set name to a mobile control class name, and you give adapter a name value of an adapter class for the specified mobile control. Listing 19-6 shows the mapping between controls and adapters in a Web.config file.

Listing 19-6: Extract from Web.config that illustrates the configuration of a device adapter set






<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<!-- Other Web.config settings -->
<mobileControls>
<device
name="HtmlDeviceAdapters"
predicateClass=
"System.Web.UI.MobileControls.Adapters.HtmlPageAdapter"
predicateMethod="DeviceQualifies"
pageAdapter=
"System.Web.UI.MobileControls.Adapters.HtmlPageAdapter">
<control name="System.Web.UI.MobileControls.Panel" adapter=
"System.Web.UI.MobileControls.Adapters.HtmlPanelAdapter"/>
<control name="System.Web.UI.MobileControls.Form" adapter=
"System.Web.UI.MobileControls.Adapters.HtmlFormAdapter"/>


<!—Adapter mappings continue ->


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













Defining a Device Adapter Set


We mentioned that you might want to write new device adapter classes for a number of reasons. For example, you might want to replace the standard device adapter with a customized version, or you might want to add device adapters that support custom controls. (As you'll learn in Chapter 20 and Chapter 21, user controls and custom controls built by inheritance or by composition use the device adapters of the standard controls from which they derive, and they rarely have custom device adapters. Controls built from scratch do have device adapters, as described in Chapter 22.)

If you're replacing a standard device adapter with a customized version, or adding configuration for a new custom mobile control and its adapters, you can update the existing device adapter set definitions in machine.config by replacing the standard device adapter class name with the custom version or by adding new lines into an existing device adapter set definition to include support for device adapters for new custom controls. Alternatively, you can define a new device adapter set that inherits all settings from an existing device adapter set using the inheritsFrom attribute of the <device> element. In the child device adapter set, control-adapter mappings defined in <control> elements override those of the same name in the parent, and you can define additional control-adapter mappings for custom controls.

You can define your own adapter sets in a Web.config file in the application directory (applies only to that application), in the Web server wwwroot directory (applies to all applications in that Web server), or in machine.config.


Device Adapter Set Inheritance


As mentioned, you can create a new device adapter set by inheriting from an existing device adapter set using the inheritsFrom attribute of the <device> element. The new device adapter set inherits all the mappings its parent defines, and you can then add new mappings or override the ones that already exist. This technique is used in Chapter 22, where a new device adapter set is defined to add support for the custom CMTable control created in that chapter. The parent adapter set can reside in the same Web.config file, a parent Web.config file, or machine.config. If the application doesn't find the named device adapter set in the current Web.config file, the runtime checks the parent and progresses upward through the configuration file hierarchy until it does find the parent. Listing 19-7 shows an example of device adapter set inheritance within a Web.config file.

There are a few important points to note about Listing 19-7. First, the device adapter set inherits from the WmlDeviceAdapters set. Therefore, all the mappings WmlDeviceAdapters defines also apply to the new device adapter set, apart from those that you override in the new set. Also, the predicate class and predicate method are exactly the same as the ones defined in the configuration of the WmlDeviceAdapters device adapters set in machine.config. The runtime calls the predicate method to determine which adapter set to use with the requesting device. As it searches through the configuration files for the device adapter set to use, it evaluates the predicate method of each adapter set until one returns a value of true. Using the default device adapter sets, the predicate method of the WmlDeviceAdapters device adapters set returns true for any device that requires WML markup. When you introduce the customizations shown in listing 19-7, the same predicate method is used to select WML browsers, but these devices will now use the NewWmlDeviceAdapters device adapters set instead of the WmlDeviceAdapters device adapters set.

Listing 19-7: Creating a new device adapter set through inheritance






<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>


<!-- Other Web.config settings-->


<mobileControls>
<device
name="NewWmlDeviceAdapters"
inheritsFrom="WmlDeviceAdapters"
predicateClass=
"System.Web.UI.MobileControls.Adapters.WmlPageAdapter"
predicateMethod="DeviceQualifies"
pageAdapter=
"System.Web.UI.MobileControls.Adapters.WmlPageAdapter">
<control
name="System.Web.UI.MobileControls.MyControl"
adapter=
"System.Web.UI.MobileControls.Adapters.WmlMyControlAdapter"/>
<!-- Place any new mappings here -->
</device>
</mobileControls>
</system.web>
</configuration>
















Warning

Where both child and parent device adapter sets use the same predicate method, the child adapter set supersedes the parent adapter set and is used instead of the parent, as long as it is evaluated and thus selected first. If the child and parent adapter set are in the same configuration file and use the same predicate method, be sure to place the definition of the child above its parent; otherwise, it will never be selected.


Writing Predicate Methods


Creating a new predicate method is something you might do only occasionally—for example, if you want to provide support for a new markup language. In ASP.NET Mobile Controls in version 1.1 of the .NET Framework and with Device Update 2 applied, the standard device adapter sets choose between HTML, cHTML, XHTML, Openwave WML, and non-Openwave WML devices. The Openwave set (UpWmlDeviceAdapters) inherits from WmlDeviceAdapters but has Openwave-specific device adapters for some of the controls. If you want to create a new device adapter set that selects a new group of client devices—different from these five existing groupings—you must write a custom predicate method. For example, some devices on the market support an enhanced version of WML version 1.2.1, known as WML version 1.3. (The official next version after WML 1.2.1 is version 2.0, which uses XHTML, but some suppliers implemented version 1.3 as an interim solution offering enhanced usability.) This version of WML is backward compatible with versions 1.1 and 1.2, so you don't have to create a new adapter set to support these devices. However, if you want to customize some of the device adapter classes so that you can take advantage of new features in WML version 1.3 on those devices that support it, you might consider creating a new device adapter set that inherits from the existing set but that overrides some or all of the existing device adapters with custom versions that render WML 1.3 markup. This adapter set needs to have a predicate method that returns true for devices that support WML 1.3.

Predicate methods, described in Table 19-3, are static methods that the runtime calls to evaluate whether the device adapter set is appropriate for the current device. The method can be in any class—existing implementations are in the page adapter class for the device adapter set. The predicate method takes one argument of the System.Web.HttpContext type and returns a Boolean value that indicates whether the device adapter set suits the current device. Within this method, you can write code that tests the capabilities of the client device. You access these capabilities through the Browser property of the HttpContext object because the Browser property returns a MobileCapabilities object.

Consider the example of a predicate method that evaluates whether a WML 1.3 adapter set is suitable for a client device, shown in Listing 19-8 below. The predicate method in this example is placed within a custom class called Wml13PageAdapter, which inherits from the standard WmlPageAdapter class. (The Page adapter class is responsible for formatting the output for a complete page of output for a particular device, incorporating the rendered output of all the individual mobile controls on the page.) The DeviceQualifies predicate method accepts an HttpContext object as a parameter and returns a Boolean value. The predicate method must return true if the requesting device can accept WML 1.3. To test whether the device can read this markup, the code gets the Browser property of the MobileCapabilities object for the requesting client device. If the device has the value Openwave13 for the Browser property, this predicate method returns true.

Listing 19-8: Predicate method example






public class Wml13PageAdapter : WmlPageAdapter
{
public static bool DeviceQualifies(HttpContext context)
{
MobileCapabilities capabilities =
((MobileCapabilities)context.Request.Browser);
bool qualifies = capabilities.Browser == "Openwave13";
return qualifies;
}
}















Note

This example tests for a specific value in the Browser property of the MobileCapabilities object of Openwave13. This is a string value that's set by the device configuration you define for the requesting device in the <browserCaps> configuration section, as described in the section "Defining Mobile Devices in Configuration Files" earlier in this chapter. It would be more logical to test the PreferredRenderingType for a value of wml13; however, at the time of this writing, the only permissible values for this property are html32, wml11, wml12, chtml10, wml20, xhtml-mp, and xhtml-basic.

If you decide to implement some custom versions of controls that take advantage of WML 1.3 features and you configure a WML13DeviceAdapterSet to use the custom controls, you'll use the predicate method shown in this example. You'll also need to ensure that you update the device configuration files so that devices that support WML 1.3 set the Browser property to the value Openwave13 so that they get to use the WML13DeviceAdapterSet when they make a request.


That's it! You've now written the predicate method for the WML 1.3 device adapter set. To use this method as the selector for the device adapter set, compile it into an assembly containing your custom device adapters, named in this example Custom13Adapters, and set the <device> element attributes like so:

        <mobileControls>
<device
name="Wml13DeviceAdapters"
inheritsFrom="WmlDeviceAdapters"
predicateClass="Custom13Adapters.Wml13PageAdapter"
predicateMethod="DeviceQualifies"
pageAdapter="Custom13Adapters.Wml13PageAdapter">



/ 145