分享
 
 
 

Smartphone 2002中使用Web Service

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Smartphone 2002中使用Web Service

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)。

Figure 1. Web Service generated documentation from ASP.NET.

如果你不能这样访问,另一个办法是使用一个支持WSDL的客户端调用Web service,并分析SOAP包。SOAP工具包支持一种utility, Trace Utility (MsSoapT3.exe).这个工具也在调试Web service时经常使用。

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

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并接收一幅地图保存到文件系统中。这可以让用户看到最后一幅下载的地图。

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错误。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有