ASP.NETWebServices开发全解析
立即解锁
发布时间: 2025-08-26 01:38:45 阅读量: 5 订阅数: 20 


Silverlight 5编程与应用实例解析
### ASP.NET Web Services 开发全解析
#### 1. 代理类的创建与更新
当添加服务引用时,Visual Studio 会创建一个代理类。该代理类的命名是在原始 Web 服务类名后加上“Client”。例如,添加对 `TestService` 的引用时,会创建名为 `TestServiceClient` 的代理类。代理类包含触发 Web 服务调用的方法和接收结果的事件,它负责处理诸如创建请求消息、发送 HTTP 请求、获取响应以及通知代码等操作。
若 Web 服务发生变化(如新方法或方法参数类型数量改变),可随时更新服务引用。操作步骤如下:
1. 重新编译 Web 应用程序。
2. 在解决方案资源管理器中右键单击服务引用。
3. 选择“更新服务引用”。
#### 2. 命令行生成代理代码
Silverlight 包含一个命令行实用工具 `slsvcutil.exe`,其功能与 Visual Studio 的服务引用功能相同。可在 Visual Studio 命令提示符中轻松运行该工具。例如,以下命令为 `TestService` 创建代理代码(假设端口号与测试 Web 服务器当前使用的端口匹配):
```
slsvcutil http://localhost:4198/ASPWebSite/TestService.svc?WSDL
```
其中,`?WSDL` 是 Web 服务的约定,用于告知 ASP.NET 提供描述 Web 服务的 Web 服务描述语言(WSDL)文档。该文档详细说明了 Web 服务的公共接口,但不暴露代码或内部工作的私有细节,Visual Studio 或 `slsvcutil` 可根据该文档生成代理代码。使用 `slsvcutil` 最常见的原因是将其作为自动化构建过程的一部分来生成代理类代码。若要查看所有可用参数的列表和描述,可在不添加参数的情况下输入 `slsvcutil`。
#### 3. 调用 Web 服务
使用代理类时,首先要导入在步骤 3 中为服务引用指定的命名空间。假设使用命名空间 `MyWebServer`,项目名为 `MySilverlightProject`,则需要以下语句:
```csharp
using MySilverlightProject.MyWebServer;
```
在 Silverlight 中,所有 Web 服务调用必须是异步的。调用方法启动调用并发送请求后,该方法会立即返回,代码可继续执行其他任务,用户也可继续与应用程序交互。当收到响应时,代理类会触发相应的代理类事件,事件名称形式为 `MethodNameCompleted`,必须处理该事件以处理结果。
以下是调用 `TestService.GetServerTime()` 方法的示例:
```csharp
// 创建代理类
TestServiceClient proxy = new TestServiceClient();
// 为完成事件附加事件处理程序
proxy.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(GetServerTimeCompleted);
// 启动 Web 服务调用
proxy.GetServerTimeAsync();
```
要获取结果,需处理完成事件并检查相应的 `EventArgs` 对象。Visual Studio 在生成代理类时,会为每个方法创建不同的 `EventArgs` 类,唯一的区别是 `Result` 属性,其类型与方法的返回值匹配。例如,`GetServerTime()` 方法与 `GetServerTimeCompletedEventArgs` 类配合使用,该类通过 `Result` 属性提供 `DateTime` 对象。首次访问 `Result` 属性时,需要使用异常处理代码,因为若 Web 服务调用失败(如服务器未找到、Web 服务方法返回错误或连接超时),会在此处抛出异常。也可检查自定义 `EventArgs` 对象的 `Error` 属性,若 `GetServerTimeCompletedEventArgs.Error` 为 `null`,则处理请求时未发生错误,可安全地从 `Result` 属性获取数据。
以下是读取结果并在 `TextBlock` 中显示的事件处理程序示例:
```csharp
private void GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e)
{
try
{
lblTime.Text = e.Result.ToLongTimeString();
}
catch (Exception err)
{
lblTime.Text = "Error contacting web service";
}
}
```
默认情况下,若未收到响应,代理类会等待一分钟后放弃。可在进行 Web 服务调用前使用以下代码配置超时时间:
```csharp
proxy.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(30);
```
#### 4. Web 服务异常处理
当 Web 服务方法抛出异常时,不能简单地在 Silverlight 代码中捕获。Web 服务的标准旨在允许任何支持 Web 的平台上的应用程序之间进行交互,不包含与特定技术(如 .NET 异常类)相关的概念。此外,出于安全考虑,Web 服务可被任何支持 Web 的应用程序使用,若 Web 服务方法返回具体详细的异常,会向潜在攻击者透露过多内部工作信息。
当调用出错的 Web 服务方法时,Web 服务器会向客户端应用程序返回通用错误消息,使用 HTTP 状态代码 500 表示内部错误。由于浏览器的安全限制,即使错误消息中有更多信息,Silverlight 应用程序也无法访问。Silverlight 会检测到错误消息并立即抛出无有用信息的 `CommunicationException`。
若要获取更详细的异常信息,可采取以下两个步骤:
1. 使用专门的 WCF 行为,在将服务器端错误消息发送到客户端之前,将其 HTTP 状态代码从 500 更改为 200(浏览器对 HTTP 状态代码为 200 的响应读取信息无限制)。
2. 需要一种机制来返回异常信息,Silverlight 包含一个 Web 服务配置选项,启用后可将异常插入错误消息。
更多信息可参考:http://msdn.microsoft.com/magazine/ee294456.aspx 。
#### 5. 配置 Web 服务 URL
添加服务引用时,自动生成的代码包含 Web 服务 URL,创建代理类实例时无需指定 URL。但这可能会带来问题,因为所有 Web 服务 URL 必须是完全限定的,不允许使用相对路径。若使用 Visual Studio 中的测试 Web 服务器,当测试 Web 服务器选择不同端口号时,运行应用程序可能会遇到问题;将最终应用程序部署到生产 Web 服务器时,也需要更新 URL。
解决此问题有两种更简单的方法:
- **方法一:配置固定端口**
若将 Web 应用程序创建为 Web 项目(而非无项目的网站),可配置 Visual Studio 在运行测试 Web 服务器时始终使用特定端口。操作步骤如下:
1. 在解决方案资源管理器中双击“属性”项。
2. 选择“Web”选项卡。
3. 在“服务器”部分,选择“特定端口”并输入要使用的端口号。
然后修改创建代理类的代码,显式设置端口:
```csharp
// 创建代理类
TestServiceClient proxy = new TestServiceClient();
// 使用项目属性中硬编码的端口
EndpointAddress address = new EndpointAddress("http://localhost:54752/ASPWebSite/TestService.svc");
// 应用新的 URI
proxy.Endpoint.Address = address;
```
- **方法二:动态更改地址**
可在代码中动态更改地址,使其与测试 Web 服务器当前使用的端口号同步。只需获取 Silverlight 页面的 URL 并找到其端口号(因为 Silverlight 页面与 Web 服务托管在同一 Web 服务器上)。示例代码如下:
```csharp
// 使用当前端口号为 TestService.svc 服务创建新的 URL
EndpointAddress address = new EndpointAddress("http://localhost:" + HtmlPage.Document.DocumentUri.Port + "/ASPWebSite/TestService.svc");
// 将新地址与代理对象一起使用
TestServiceClient proxy = new TestServiceClient();
proxy.Endpoint.Address = address;
```
使用类似代码可根据当前 Silverlight 页面创建 URL,只要将 Web 服务
0
0
复制全文
相关推荐







