Smartphone 2002中使用Web Service<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Chung Webster
Microsoft UK, Developer Services
January 2003
Applies to:
Microsoft Smartphone 2002 Software
Microsoft ASP.NET
Microsoft MapPoint .NET
摘要:学习如何创建一个连接提供地理信息的ASP.NET Web service的Smartphone客户端程序。注意示例代码只是用来示范如何使用,并不被保证和支持。
Download the Microsoft Software Development Kit for Smartphone 2002.
Download the Smartphone 2002 and Web Services source code.
Contents
Introduction
Web Services Basics
Smartphone Web Services
MapMobile & MapPoint .NET Web Service
The SmartMap Client
Summary
About the Author
Introduction
介绍
Orange SPV——第一种被正式推出的运行Smartphone 2002的移动电话——已经开始在市面上出售了,因此现在是开始开发Smartphone应用程序的时候了。在这篇文章中,我们将创建一个Smartphone客户端,用来连接一个提供地理信息的ASP.NET Web service。这篇文章假定读者具有Web services, ASP.NET 和 Win32编程的基础知识。
.NET framework有一套类库可以帮助我们连接(consume)Web services,从分析WSDL文档到自动创建一个代理类进行编程调用。这使得大部分Web services的编程调用显得很微不足道;然而Compact Framework是不能被Smartphone使用的,因此我们需要看一下其他的选择了。
COM可以使用Soap工具包,但同样不能用于Smartphone;但是,我们可以用它来帮助追踪我们的调用。
在没有这些技术的情况下,我们仍然可以编程调用一个Web Service,为此我们需要看一下Web Service的格式和传输。在.NET 1.0 Web services中使用两种信息标准,SOAP和WSDL.
Web Services基础
没有一个基于API的SOAP帮助我们连接Web services,我们不得不直接处理SOAP消息,它们的格式在WSDL文档中被指定。注意使用WSDL的一个好处是计划信息在类型元素中。
对于Smartphone来说,我们必须构造自己的SOAP消息,使他们能够被Web service正确接受。这些消息通过HTTP POST被发送到服务器,我们的客户端等待SOAP响应。这个过程包括分析、检查SOAP错误,并返回处理过的值。这看来需要付出巨大的努力。无论如何,在实际中这和SOAP工具包提供的底层API是十分相似的。
从纯粹的WSDL中手动构造一个SOAP消息是件复杂的任务,比如显示map.wsdl这需要查找正确的操作元素,寻找输入消息,并映射正确的类型。如果Web service使用ASP.NET,简单的方法是查看产生的asmx页,选择Webmethod,并查看SOAP请求的例子(见图1)。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 337.5pt; HEIGHT: 315pt" alt="" type="#_x0000_t75"><img o:href="http://msdn.microsoft.com/library/en-us/dnsmtphn/html/sphoneweb_fig1.gif" src="/Develop/ArticleImages/20/20289/CSDN_Dev_Image_2003-8-61602420.gif"><font face="宋体"></font></shape>
Figure 1. Web Service generated documentation from ASP.NET.
如果你不能这样访问,另一个办法是使用一个支持WSDL的客户端调用Web service,并分析SOAP包。SOAP工具包支持一种utility, Trace Utility (MsSoapT3.exe).这个工具也在调试Web service时经常使用。
<shape id="_x0000_i1026" style="WIDTH: 337.5pt; HEIGHT: 282.75pt" alt="" type="#_x0000_t75"><img o:href="http://msdn.microsoft.com/library/en-us/dnsmtphn/html/sphoneweb_fig2.gif" src="/Develop/ArticleImages/20/20289/CSDN_Dev_Image_2003-8-61602422.gif"><font face="宋体"></font></shape>
Figure 2. Trace Utility, from Soap Toolkit 3.0
Smartphone Web Services
在上面的请求中,我们可以看到,构造一个SOAP消息是很容易的。在这个例子中,我创建了一个类SoapWriter,提供底层函数用来写一个SOAP消息。
#include "Soap.h"
SoapWriter *pSoap = new SoapWriter();
pSoap->StartEnvelope();
pSoap->StartBody();
pSoap->StartElement(L"GetLatLong", L"http://mapmobile");
pSoap->WriteElementString(L"addressLine", L"new bond street");
pSoap->WriteElementString(L"city", L"bath");
pSoap->StartElement(L"postCode");
pSoap->EndElement(L"postCode");
pSoap->WriteElementString(L"country", L"UK");
pSoap->EndElement(L"GetLatLong");
pSoap->EndBody();
pSoap->EndEnvelope();
pSoap->FinalizeSoap();
为了发送这个SOAP请求到Web service,我将使用WinInet API。一般来说,WinInet被用于HTTP和FTP通信。这是一个提供Internet访问、不需要WinSock编程的高级API。幸运的是,Web service使用SOAP调用是基于HTTP基础上的。
为了容易地发送我们的SOAP请求,我创建了一个SoapConnector类,允许我们post SOAP请求,并得到响应。一旦连接到Web service,客户端可以执行多重调用,并使用accessors来接受SOAP响应。
#include "Soap.h"
SoapWriter *pSoap = new SoapWriter();
//Create the SOAP request here
SoapConnector *pCon = new SoapConnector();
pCon->Init();
//Connect to the server and Web service
pCon->Connect(L"http://chungw02:8080/mapmobile/map.asmx");
//Invoke with the Soap Message and SoapAction
pCon->Invoke(pSoap, L"http://mapmobile/GetLatLong");
//Extract out the response
int iLen = 0;
pCon->GetSoapLength(&iLen);
TCHAR *pResponse = new TCHAR[iLen+1];
pCon->GetSoap(&pResponse);
XML可以被客户端接收,然后下载到DOM分析器中,并返回处理后的值。在这个例子里,我创建了一个封装msxml 中IXMLDOMDocument接口的类;在这里需要的COM将被介绍。
#include "Soap.h"
//Read SOAP Response
pSoapReader = new SoapReader();
pSoapReader->Init();
//Load the SOAP response by passing in a SoapConnector or Xml string
pSoapReader->LoadXml(pCon);
一旦被加载,DOM可以通过m_pDom对象被访问,来选择节点值或者运行Xpath查询。
MSXML::IXMLDOMNode *pNode = NULL;
MSXML::IXMLDOMNodeList *pNodeList = NULL;
MSXML::IXMLDOMNode *pTextNode = NULL;
TCHAR *lpNodeValue = NULL;
TCHAR *XPath = new TCHAR[50];
_tcscpy(XPath, L"/soap:Envelope/soap:Body/Node");
VARIANT vNodeVal;
HRESULT hr;
//using previous created pSoapReader
try {
//Select node
hr = pSoapReader ->m_pDom->selectSingleNode(XPath, &pNode);
if (FAILED(hr))
__leave;
if (pNode == NULL)
__leave;
//Get child node
hr = pNode->get_childNodes(&pNodeList);
if (FAILED(hr))
__leave;
//Get text node
hr = pNodeList->get_item(0, &pTextNode);
if (FAILED(hr))
__leave;
//Get value of text node
VariantInit(&vNodeVal);
hr = pTextNode->get_nodeValue(&vNodeVal);
if (FAILED(hr)) {
VariantClear(&vNodeVal);
__leave;
}
//Assign the value to lpNodeValue
lpNodeValue = TCHAR[SysStringLen(vNodeVal.bstrVal) + 1];
_tcscpy(lpNodeValue, vNodeVal.bstrVal);
VariantClear(&vNodeVal);
//Do something with lpNodeValue
}
__finally {
if (pNode != NULL)
pNode->Release();
if (pNodeList != NULL)
pNodeList->Release();
if (pTextNode != NULL)
pTextNode->Release();
if (lpNodeValue !=NULL)
delete[] lpNodeValue;
}
作为选择,一个帮助方法,SelectSingleTextNode提供解析出的文本节点。分派TCHAR长度以适合文字节点的值。
//Note these are allocated by the helper method SelectSingleTextNode
TCHAR *latitude = NULL;
TCHAR *longitude = NULL;
//using previous created pSoapReader
pSoapReader->SelectSingleTextNode(L"/soap:Envelope/soap:Body/GetLatLongResponse/latitude", &latitude);
pSoapReader->SelectSingleTextNode(L"/soap:Envelope/soap:Body/GetLatLongResponse/longitude", &longitude);
//Do something with return values
//
//Cleanup
if (latitude != NULL)
delete[] latitude;
if (longitude != NULL)
delete[] longitude;
我们调用的Web service将返回文字节点中包含数据的SOAP消息,因此SelectSingleTextNode方法提供一个有用的机制从Web service调用中解析出数据。SoapReader类可以被扩展用来包括其他的帮助方法,如果你经常需要从不同的节点轴解析不同的数据、EG, 比如属性数据或者评估一个nodeset。
迄今为止,SoapWriter, SoapConnector, 和 SoapReader用来提供从Web service上构造、调用和阅读请求的功能函数。为了使用这些类实现一个客户端,我们需要理解SOAP消息的格式。下面,我们将看到如何创建一个Web service和创建一个Smartphone客户端。
MapMobile & MapPoint .NET Web Service
这个DEMO程序从一个Web service中接收地图信息,并显示到Smartphone中。地理信息查找和地图信息由MapPoint.NET提供——一个商业Web service。由于Smartphone的最终用户不一定有自己的MapPoint .NET帐号,我创建了一个封装Web service,MapMobile,用来调用和识别MapPoint .NET。对于Smartphone 2002,没有认证提供者,因此如果我想直接和MapPoint .NET对话,我不得不手工实现认证头。封装类的另外的原因是可以改变地理信息的提供者,而不会影响到最终用户,例如移植MapPoint NET 2.0 到 3.0。
因为已经有文章描述如何使用MapPoint .NET和其SDK,我不准备包括详细的细节。更多的信息,包括评估帐号的安装,请访问MapPoint .NET.查看service的WSDL,请访问http://staging.mappoint.net/standard-30/default.htm。
<shape id="_x0000_i1027" style="WIDTH: 337.5pt; HEIGHT: 118.5pt" alt="" type="#_x0000_t75"><img o:href="http://msdn.microsoft.com/library/en-us/dnsmtphn/html/sphoneweb_fig3.gif" src="/Develop/ArticleImages/20/20289/CSDN_Dev_Image_2003-8-61602424.gif"><font face="宋体"></font></shape>
Figure 3. MapMobile Architecture
我们的包装service提供两个简单的Web service method,使客户端可以定位并显示一幅地图。第一次调用返回地址的经纬度,第二次调用返回一个包含GIF图片的byte array。
[WebMethod]
[SoapHeader("_phoneNumber", Direction=SoapHeaderDirection.In)]
public void GetLatLong(string addressLine, string city, string postCode, string country, out double latitude, out double longitude)
[WebMethod]
[SoapHeader("_phoneNumber", Direction=SoapHeaderDirection.In)]
public byte[] GetMap(double latitude, double longitude, double zoom, int width, int height, string tag)
为了防止无限调用MapMobile Web service,一个包含Smartphone电话号码的SOAP头被包括在所有调用中。在服务器端,该头将在对照有效号码列表进行检查。如果调用失败,一个SOAP错误将被返回到客户端。这个验证机制仅仅是个例子,很显然它不能禁止使用一个有效号码的欺骗调用。这里有许多依赖你的Web service安全选项可用,你可以不选择认证,使用数字签名,或者使用新的Global XML Web Services Architecture (GXA).
更多的关于未来调用安全Web service的信息,请访问Security in a Web Services World: A Proposed Architecture and Roadmap。
The SmartMap Client
该客户端程序提供一个输入屏幕,用于输入一个地址。然后它会调用MapMobile Web service并接收一幅地图保存到文件系统中。这可以让用户看到最后一幅下载的地图。
<shape id="_x0000_i1028" style="WIDTH: 267.75pt; HEIGHT: 334.5pt" alt="" type="#_x0000_t75"><img o:href="http://msdn.microsoft.com/library/en-us/dnsmtphn/html/sphoneweb_fig4all.gif" src="/Develop/ArticleImages/20/20289/CSDN_Dev_Image_2003-8-61602426.gif"><font face="宋体"></font></shape>
Figure 4. SmartMap User Interface
我们的客户端应用程序包括一个splash screen(我们的main window class)和三个对话框(输入屏幕,Web service调用状态和地图显示)。最初,splash window被显示,紧跟着是Find Location对话框。该设备的电话号码也被提取和保存,为了在SOAP头中使用。该调用在模拟器中不工作,因此,如果该调用失败,我们设置一个1234567890的号码作为测试号码。
TCHAR *g_PhoneNumber = new TCHAR[40];
SMS_ADDRESS pAddr;
//Get the phone number
SmsGetPhoneNumber(&pAddr);
_tcscpy(g_PhoneNumber, pAddr.ptsAddress);
当用户选择Search菜单选项,应用程序构造一个正确的SOAP调用给MapMobile Web service.这包括包含设备电话号码的SOAP头。
SoapWriter *pSoap = new SoapWriter();
sw->StartEnvelope();
//Construct the header
sw->StartHeader();
sw->StartHeaderElement(L"MapMobileHeader", L"http://mapmobile");
sw->WriteHeaderElementString(L"PhoneNumber", g_PhoneNumber);
sw->EndHeaderElement(L"MapMobileHeader");
sw->EndHeader();
//Soap Body
sw->StartBody();
//Construct the SOAP body here..
sw->EndBody();
sw->EndEnvelope();
sw->FinalizeSoap();
一旦这些完成后,SoapConnector可以被加载到SoapReader中,解析base64 encoded数据。
TCHAR *map64;
//This allocates memory into the target variable
hrSearch = pSoapReader->SelectSingleTextNode(L"/soap:Envelope/soap:Body/GetMapResponse/GetMapResult", &map64);
我们将始终检查我们的HRESULTs,如果SoapReader失败,然后检查响应是否包含SOAP错误。
分享到:
相关推荐
### 使用C#开发SmartPhone程序入门:关键技术与实践 #### 引言 随着移动设备的普及和技术的不断进步,开发针对智能手机的应用程序已成为IT领域的热门话题。本文旨在为初学者提供一个全面的指南,帮助他们了解如何...
- **x86编译器需求**:由于模拟器运行依赖于x86架构的编译代码,因此在eVC++中使用模拟器时,需确保选择了x86编译器的安装。若在自定义安装时未选择,可通过控制面板的“添加/删除程序”功能进行补充安装。 #### 五...
MTK平台工厂多路升级刷机工具MTK_SmartPhone_Multi-port Download_v3.1748.00.00,支持16路刷机 1、需要将CheckSum_Generate_exe_v5.1748.00.00文件夹中所有文件拷入rom包中; 2、点击CheckSum_Gen.exe,生成...
《Microsoft Smartphone Programming》一书是针对使用C#进行智能手机应用开发的专业指南,涵盖了Windows Mobile操作系统。这本书通过详细的实例代码帮助读者理解和掌握如何在移动设备上构建功能丰富的应用程序。...
在你提供的资源中,我们可以看到一系列与Symbian OS和SmartPhone开发相关的教程,这些都是早期智能手机开发的重要平台。以下是一些关键知识点的详细说明: 1. **Symbian OS**:Symbian是一个基于微内核的实时操作...
I believe in the W3C’s principle of One Web—that services and information on the web should be thematically consistent and accessible to all kinds of devices, without regard to differences in ...
描述中提到的开发环境主要是利用Visual Studio .NET 2003来构建针对Smartphone设备的应用程序,需要的基础知识包括C# WinForm编程、WebService基本概念与使用以及对Smartphone设备的熟悉。 Windows Mobile是一款由...
在实际操作中,使用"HTC SmartPhone USB Sync"时,用户需要确保电脑的USB接口正常,手机开启USB调试模式(如果需要),并且正确安装了驱动程序。一旦驱动安装成功,手机将被电脑识别,用户可以通过同步软件在两者...
在VB2005中编写代码与早期版本的VB.NET相似,但由于面向的是嵌入式系统的Smartphone手机,因此在变量和控件的使用上需要特别注意。例如,需要编写事件处理函数来响应菜单按钮的点击事件,这些函数将控制计时器的启动...
《SmartPhone智能手机VS2005开发指南》是一本针对Windows Mobile智能手机软件开发的专业教程,主要使用Visual Studio 2005(VS2005)作为开发工具。该教程以图文并茂的方式,深入浅出地介绍了智能设备应用程序开发的...
7. **技术支援**:通常会配备详细的使用指南或在线技术支持,帮助用户解决在使用过程中遇到的问题。 在使用MTK_SmartPhone_Multi-port Download_V1.9前,需要注意以下几点: 1. **备份数据**:在进行刷机操作前,...
本文将详细介绍名为"qualcomm-smartphone-write-imei-tool-v1.01.zip"的工具,以及如何使用它来改串。 IMEI,全称为国际移动设备识别码,是全球移动通信系统分配给手机的唯一标识符。它由15位数字组成,用于区分每...
This application has been designed for low memory consumption and CPU usage, specially used for smartphone and tablet. Hey, it's free and you don't need a root access to run Palapa Web Server! # ...