ASP.NET底层架构探索之再谈.NET运行时(一)
本文将重点讲解如何为特定的硬件设备自定义ASP.NET Web移动程序,以及使用模板自定义Form和Panel等控件。通过属性重写这个特性,使ASP.NET Web移动程序可以根据移动设备的硬件功能,为特定的硬件指定其控件的属性值。例如,应用程序可能需要一个Label控件在一些设备上显示较长的文本,而在另一些设备上显示较简短的文本。这就需要我们为每个控件都提供一组属性,应用程序可以针对各个设备重写这些属性。所有的ASP.NET移动控件都具有默认的外观和布局。对于ASP.NET移动控件,你可通过设置属性或使用样式来改变移动控件的默认外观。你还可以使用模板自定义某些移动控件的外观。本章还将重点介绍模板和模板集,以及它们的使用方法。
自定义的方式
在前面的几个专题中,我们提过如何使用设备筛选器为特定设备进行自定义。除此之外,我们还可以使用模板化技术和属性重写功能使你可以自定义你的应用程序,以便对特定的设备类型以不同的方式呈现控件。如果你在.aspx页面中为一个控件使用上述的任何一种自定义方法,都可以使用一个名为DeviceSpecific/Choice构造的移动控件语法。DeviceSpecific/Choice构造通常是为特定于设备的选项模板集以及控件内在多个备选内容之间指定一个选项。例如,下面的代码是一个Label控件的声明语法,在这个声明中包含了一个用来鉴别当前浏览器是否支持HTML的DeviceSpecific/Choice构造。
<mobile:Label id="Label1" runat="server" Text="Default text">
<DeviceSpecific>
<Choice Filter="isHTML32" Text="Text for selected devices" ></Choice>
</DeviceSpecific>
</mobile:Label>
其中Filter属性指定了一个设备筛选器,该设备筛选器其名称为isHTML32,它用来鉴别一个移动设备是否内置了HTML浏览器。如果内置了HTML浏览器的话,将会在Label控件上应用"Text for selected device"这段文本。相反的,就不作任何的显示。正如上述的代码所示,在<DeviceSpecific></DeviceSpecific>内通常包含一个或多个<Choice>元素,每个元素都包含指定如何根据目标设备功能计算选项的属性。运行时依次计算每个选项,并使用成功计算出的第一个选项(这和C#里的switch case语句非常相似)。
在开始学习如何定义一个设备筛选器前,先让我们先了解一些基本的概念,例如属性重写和模板化的具体含义。
属性重写
一般情况下,我们开发的ASP.NET Web移动程序并不是针对某个具体的设备,而是可以根据移动设备硬件特性的不同,通过适应性的调整从而可以在几乎所有的硬件设备上进行良好的呈现。
但是因为品牌和型号的不同,这些移动设备间就不可避免地存在一些差异。例如支持的颜色、屏幕大小、输入功能以及浏览器使用的标记语言等。前面提到过,ASP.NET控件是可以被几乎所有的硬件设备支持的,因为它们本身就具有适应性调整的功能,而且控件设置的属性值也会伴随ASP.NET控件应用到具体的应用程序中,并不会因为硬件设备的不同使属性值不同。但是,在某些情况下你可能舍弃默认的呈现,采用自定义的呈现方式。一个典型的例子就是字符的显示,例如我们使用Label控件进行字符串的显示,在一些屏幕较小的设备上,每一行显示的字符数也是较少的,因此我们可以为该控件的Text属性设置为"我们使用ASP.NET",而针对一些大屏幕的设备,我们可以将Label控件的Text属性设置为"我们使用ASP.NET构建一个功能完善的移动应用程序",正是因为属性重写功能,我们才可以使用上述的方法来构建一个针对不同移动设备的硬件特性做出最好呈现的ASP.NET Web移动应用程序。
模板
Form、Panel、List和ObjectList等移动控件都是模板化的控件。开发人员通常使用模板来改变或丰富应用程序的外观或内容。例如,如果为Form控件指定并选择了页眉或页脚模板,则该模板中包含的标记将被添加到窗体内容中,分别作为页眉或页脚进行呈现。请注意模板不同于样式,模板定义要显示的内容和控件。当应用程序呈现模板附加到的控件时,即会呈现模板。而样式指定内容和控件的外观,您的应用程序可在不使用模板的情况下使用样式,它也可在模板内将样式应用于您定义的移动控件。 除了模板外,ASP.NET移动控件在此基础上还扩展了一个新的模型,并引入了模板集的概念。模板集是由模板组成的集合。但是,单个模板化控件可能引用多个模板集,而每个模板集都具有不同的特定于设备的条件。模板集的具体实现将在后续章节具体介绍。
设备筛选器详解
使用设备筛选器,应用程序可为特定硬件设备或设备类别自定义控件的外观。该自定义基于用来浏览应用程序的硬件设备的功能。 例如,假设开发人员正在开发主要用于支持位图 (.bmp) 图像的特定品牌手持式设备的应用程序。在此设备上,开发人员决定同时用来自.bmp文件的文本和图标显示List控件中的所有项。通过使用设备筛选器,应用程序可检测到它是否正在目标手持式设备上被用户浏览。这会导致应用程序使用同时用文本和图标显示列表项的设备特定的模板。此技术可为特定硬件设备自定义应用程序。进一步扩充此示例,假设您还希望可在显示.gif图像的任意类型设备上浏览该应用程序。您的应用程序可应用检测程序何时在此类设备上使用的设备筛选器。在该情况下,该程序指定使用文本和列表项图标的 .gif 图像(而不是.bmp图像)显示列表项的模板。这就为一类设备自定义了应用程序。
设备筛选器可完成的一些其他任务包括:
■ 根据设备类型选择样式。
■ 在支持使用更为丰富的表现形式呈现控件的设备上,我们可以尽量利用该硬件设备的 性能,使用一些更加细致的、具体的呈现方式。
■ 在显示功能受限制的设备上,使用更为简单的表现形式呈现控件。
在DeviceSpecific/Choice构造中的<Choice>元素依赖于移动设备的功能。当你使用某移动设备请求一个ASP.NET移动页面时,首先就会将包含该移动设备型号和内置浏览器等信息通过HTTP文件头传送到服务器端,这时服务器就会根据HTTP文件头传送的这些信息构建一个System.Web.Mobile.MobileCapabilities对象,以此来响应客户端请求。而设备筛选器就是利用MobileCapabilities对象的一些只读属性进行工作的。一个典型的例子就是设备筛选器如何鉴别那些支持HTML 3.2标记语言的浏览器,实现这种鉴别就是检测和客户请求相关的MobileCapabilities对象的PreferredRenderingType属性值是否为"html32",是的话就是支持HTML 3.2标记语言的浏览器。
注意,MobileCapabilities对象的各个属性是和浏览页面的移动设备戚戚相关的。例如,当使用Pocket Internet Explorer浏览器请求页面时,MobileCapabilities对象的Browser属性将被设置为"Pocket IE", PreferredRenderingType属性值设置为"html32",而ScreenPixelsWidth 和ScreenPixelsHeight属性取决于移动设备的具体型号,因为Pocket PC、Smartphone和Windows CE .NET都可以使用Pocket Internet Explorer浏览器,但是这些设备屏幕的分辨率是不同的。
因为不同移动设备使用的浏览器是不同的,因此相应的MobileCapabilities对象各个属性也存在差异。如果你要查看特定浏览器的MobileCapabilities对象,你可以在C:\WINDOWS\Microsoft.NET\Framework\[版本号]\CONFIG\Browsers目录下,查看openwave、Pocket Internet Explorer、palm和nokia等众多浏览器的信息。下面是openwave浏览器对应文件的一段代码片断,在使用该浏览器请求页面时,这些信息就会通过HTTP文件头传送到服务器端,并构建具有类似属性值的MobileCapabilities对象。
<capabilities>
<capability name="browser" value="Phone.com" />
<capability name="canInitiateVoiceCall" value="true" />
<capability name="canSendMail" value="false" />
<capability name="deviceID" value="${deviceID}" />
<capability name="deviceVersion" value="${deviceVersion}" />
<capability name="inputType" value="telephoneKeypad" />
<capability name="isMobileDevice" value="true" />
<capability name="majorVersion" value="${browserMajorVersion}" />
<capability name="maximumRenderedPageSize" value="1492" />
<capability name="minorVersion" value="${browserMinorVersion}" />
<capability name="numberOfSoftkeys" value="2" />
<capability name="optimumPageWeight" value="700" />
<capability name="preferredImageMime" value="image/vnd.wap.wbmp" />
<capability name="preferredRenderingMime" value="text/vnd.wap.wml" />
<capability name="preferredRenderingType" value="wml11" />
<capability name="requiresAdaptiveErrorReporting" value="true" />
<capability name="rendersBreakBeforeWmlSelectAndInput" value="true" />
<capability name="rendersWmlDoAcceptsInline" value="false" />
<capability name="rendersWmlSelectsAsMenuCards" value="true" />
<capability name="requiresFullyQualifiedRedirectUrl" value="true" />
<capability name="requiresNoescapedPostUrl" value="true" />
<capability name="requiresPostRedirectionHandling" value="true" />
<capability name="supportsRedirectWithCookie" value="false" />
<capability name="type"
value="Phone.com${browserMajorVersion}" />
<capability name="version"
value="${browserMajorVersion}${browserMinorVersion}" />
</capabilities>
<%@ Page Inherits="System.Web.UI.MobileControls.MobilePage"
Language="c#" %>
<script language="c#" runat="server">
public void Page_Load(Object sender, EventArgs e)
{
System.Web.Mobile.MobileCapabilities currentCapabilities;
MobileCapabilities currentCapabilities = (MobileCapabilities)Request.Browser;
// 创建一个MobileCapabilities对象来获取浏览器的信息
if(currentCapabilities.PreferredRenderingMIME=="text/html")
{
Label2.Text = "你使用的是支持HTML的移动设备";
//如果是支持HTML的移动设备的话,显示上面的文本信息
}
else if(currentCapabilities.PreferredRenderingMIME == "text/vnd.wap.wml")
{
Label2.Text = "你使用的是支持WML的移动设备";
//如果是支持WML的移动设备的话,显示上面的文本信息
}
Label1.Text = "屏幕的宽度(字符数): " + currentCapabilities.ScreenCharactersWidth;
//显示当前移动设备每一行可以显示的字符数
}
</script>
<Mobile:Form runat="server" id=frmTemplate >
<mobile:label ID="Label1" runat="server" />
<mobile:label ID="Label2" runat="server" />
</Mobile:Form>
提示:在某些情况下,某特定移动设备的MobileCapabilities对象获得的属性值并不是你期望的值。例如,我们经常在开发过程中直接使用桌面的IE来测试程序,你也许会认为PreferredRenderingType属性值为"html40",而实际上这个值为"html32",这是因为ASP.NET移动控件只支持HTML 3.2,所以发送到桌面IE的标记语言依然是HTML 3.2。 当然,你还可以通过代码的方式将请求页面的浏览器信息通过MobileCapabilities对象显示页面上,代码如下:MobileCapabilities的属性
MobileCapabilities类包含了大量的属性,我们可以使用这些属性来获取移动设备及其浏览器 的相关信息。关于该类的具体细节你可以查看MSDN,在这里我们只列举出一些常用的属性:
属性 | 说明 |
Browser | 浏览器的类型。例如Pocket IE、Microsoft Mobile Explorer、 i-mode、Nokia、Openwave和Ericsson等。 |
CanInitiateVoiceCall | 当该设备的浏览器可以启动语音呼叫时返回true值 |
CanSendMail | 如果该设备的浏览器支持邮件的发送,就返回true值 |
HasBackButton | 如果该浏览器有一个专用的"上一步"按钮的话,则返回true值 |
InputType | 返回浏览器支持的输入类型,包括virtualKeyboard、telephoneKeypad和keyboard等值 |
IsColor | 该设备是否支持颜色显示,是的话返回true值。 |
MaximumSoftkeyLabelLength | 返回软键标签可显示的文本的最大字符数 |
MobileDeviceManufacturer | 返回移动设备制造商的名称,如果为未知的话返回的是unknown |
MobileDeviceModel | 获取移动设备的型号名(如果已知) |
NumberOfSoftkeys | 返回移动设备上软键的数目。 |
PreferredImageMime | 返回浏览器通常首选的图像内容类型的MIME类型。这些值包括image/gif、image/jpeg、image/vnd.wap.wbmp和image/bmp |
PreferredRenderingMime | 返回浏览器通常首选的内容类型的MIME类型。这些值包括text/html和text/vnd.wap.wml |
PreferredRenderingType | 返回一个指出该浏览器使用的标记语言及版本信息的字符串,这些字符串通常为html32、wml11、wml12或者chtml10 |
ScreenBitDepth | 返回屏幕的显示深度(以每像素位数为单位) |
ScreenCharactersHeight | 返回显示的近似高度(以字符行为单位) |
ScreenCharactersWidth | 返回显示的近似宽度(以字符为单位) |
ScreenPixelsHeight | 返回显示的近似高度(以像素为单位) |
ScreenPixelsWidth | 返回显示的近似宽度(以像素为单位) |
SupportsIModeSymbols | 获取一个值,该值指示浏览器是否支持i-mode符号。 |
SupportsJPhoneSymbols | 获取一个值,该值指示浏览器是否支持J-Phone特定的图片符号。 |
我们可以使用HttpRequest对象的Browser属性指向MobileCapabilities对象的实例,然后可以使用此实例来读取请求浏览器和设备的功能。下面是测试MobileCapabilities对象的某个属性的代码片断:
MobileCapabilities capabilities = (MobileCapabilities)Request.Browser;
if (capabilities.ScreenPixelsWidth > 120)
{
// 为大屏幕的移动设备添加的代码
}
else
{
//为小屏幕的移动设备添加的代码
}
在下一节中,将介绍如何在ASP.NET移动站点程序中定义一个设备筛选器,以及设备筛选器的两种不同类型的具体实现。