16.3 使用Web服务
使用Web服务的第一步是使用背景菜单中的Add Web Reference菜单项为Web服务增加一个引用。然后会看到Add Web Reference对话框(参见图16-4),在此可以浏览服务的URL。一旦点击Go按钮,就会检查服务,查看是否有Web方法(有WebMethod性质的方法),如果有则显示在窗口的下半部分。然后为这个Web引用指定一个名(将其增加到解决方案时,这会成为Web服务的名),再点击Add Reference按钮(参见图16-5)。

图16-4 增加Web引用

图16-5 对Web引用命名
一旦增加了引用,可以像访问其他任何类型一样访问这个引用。例如,代码清单16-3显示了如何实例化一个Web服务并调用一个方法。在这个例子中,使用GetShippers方法(将返回一个DataSet)作为一个表格的数据源。
代码清单16-3 同步地使用一个Web服务
localhostNorthwind.Northwind nws =
new localhostNorthwind.Northwind();
GridView1.DataSource = nws.GetShippers();
GridView1.DataBind();
如代码清单16-4所示,向Web服务传递参数与其他方法调用没有两样。在此调用了InsertShipper方法,并传入两个TextBox域的值。
代码清单16-4 向Web服务传递参数
localhostNorthwind.Northwind nws =
new localhostNorthwind.Northwind();
int ShipperID = nws.InsertShipper(
ShipperNameTextBox.Text, PhoneNumberTextBox.Text);
ShipperIDLabel.Text = "ShipperID = " & ShipperID.ToString();
16.3.1 异步调用Web服务
调用Web服务时,总是调用另一个机器(通常在因特网上),相应地会处理一个相当慢的服务(这是与标准方法调用相比,因为标准方法调用是进程中调用)。因此,应当考虑采用异步模式来调用Web服务。
在ASP.NET 1.1中,必须使用代理创建的Begin和End方法,如代码清单16-5所示。首先调用Begin方法,传入一个回调,这是Web服务完成时要运行的方法。
代码清单16-5 ASP.NET 1.1中的异步模式
private System.IAsyncResult _asyncResult;
private void Page_Load(object sender, System.EventArgs e)
{
localhost.Northwind nws = new localhost.Northwind();
_asyncResult = nws.BeginGetShippers(_name,
new AsyncCallback(WriteResult), null);
}
private void WriteResult(IAsyncResult result)
{
DataSet result = _service.EndGetShippers(result);
}
ASP.NET 2.0中仍支持这种模式,不过推荐使用另一种新模式,如代码清单16-6所示。可以使用Async方法调用事件,并使用Completed事件来处理结果。Completed事件在Web服务调用完成时产生。如代码清单16-5所示,这里GetShippersCompleted事件绑定到一个名为_service_GetShippersComplete的事件处理器(如果需要,可以使用一个匿名方法)。然后用一个GetShippersAsync调用异步地启动Web服务,完成时就会产生这个GetShippers- Completed事件。
在事件中,第二个参数包含一个Result属性,这是Web服务调用的具体结果,在此,这个结果只是用作为一个表格的数据源。
代码清单16-6 异步地使用一个Web服务
private localhostNorthwind.Northwind _service;
protected void Button2_Click(object sender, EventArgs e)
{
_service = new localhostNorthwind.Northwind();
_service.GetShippersCompleted +=
new localhostNorthwind.GetShippersCompletedEventHandler(
_service_GetShippersComplete);
_service.GetShippersAsync();
}
void _service_GetShippersComplete(object sender,
localhostNorthwind.GetShippersCompletedEventArgs e)
{
GridView1.DataSource = e.Result;
GridView1.DataBind();
}
对于异步地处理Web服务来说,这种模式更为简单,也更为直观。
16.3.2 处理错误
与其他代码中一样,要采用同样的方法(即使用异常)来处理Web服务的错误。通常只处理网络异常(例如服务不可用)或SOAP异常。可以使用SoapException(位于System. Web.Services.Protocols命名空间中)来检测特定问题,或者使用WebException(位于System.Net命名空间中)检测网络问题,如代码清单16-7所示。
代码清单16-7 捕获SOAP异常
try
{
localhostNorthwind.Northwind nws =
new localhostNorthwind.Northwind();
int ShipperID = nws.InsertShipper(
ShipperNameTextBox.Text, PhoneNumberTextBox.Text);
ShipperIDLabel.Text = "ShipperID = " + ShipperID.ToString();
}
catch (SoapException soapex)
{
MessagLabel.Text = "SOAP Exception" +
soapex.ToString();
}
catch (WebException webex)
{
}
WebException将处理网络问题,如401错误,而SoapException用于处理Web服务中出现的异常。利用SoapException,不能访问内部异常(否则将为null),因为这是从Web服务收到的一个XML SOAP包,而不是一个本地异常对象。不过,确实可以访问消息、栈轨迹、帮助链接等等,这与其他异常一样。如果Web服务代码中产生异常,这些异常会封装在一个SoapException中。







