Silverlight 简介 Part.6(Web 服务)

       Silverlight 应用程序使用服务器端代码的最有效方式就是通过 Web 服务。基本思路很简单,ASP.NET 网站上提供 Web 服务,你的 Silverlight 程序可以调用这个 Web 服务中的方法。Web 服务的代码可以执行服务器端的任务、访问服务器端的数据库、甚至可以使用诸如验证和会话状态之类的 ASP.NET 服务。更重要的是,由于页面不会回发,你的 Silverlight 程序可以持续运行而不会中断。

       Silverlight 应用程序支持多种 Web 服务技术,包括基于 SOAP 的服务、返回 XML 或 JSON 数据的简单 REST 服务以及用 .NET 构建的全功能的 WCF 服务。本文专注于 WCF 服务,这是 Silverlight 应用程序的最好选择。

创建 WEB 服务

       要为 Silverlight 应用程序创建一个 WCF 服务,右击 ASP.NET 站点,添加一个 “启用 Silverlight 的 WCF 服务”。要强调的是,启用 Silverlight 的 WCF 服务是一个支持基本 HTTP 绑定的 WCF 服务,而不是更为严格的 WS-* 标准。但它依然可以响应当前请求来访问 HTTP 上下文,并且使用从 cookies 到缓存的方式来提供所有资源。要与当前 HTTP 内容交互,要使用 HttpContext.Current 静态属性

       在代码中添加一个新方法,并确保加上 OperationContract 特性。像下面一样添加一个返回服务器当前时间的方法:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)]
public class SilverlightTestService
{
    [OperationContract]
    public DateTime GetServerTime()
    {
        return DateTime.Now;
    }
}

添加 WEB 引用

        在 Silverlight 应用程序中使用 Web 服务的方法与在完整的 .NET 应用程序中使用 Web 服务的方法大致一样。参考以下步骤:

  • 右击 Silverlight 项目,添加服务引用
  • 在地址输入指向这个 Web 服务的 URL(“发现”按钮可以寻找当前的解决方案中所有 WEB 服务)
  • 输入这个自动生成类的 C# 命名空间,单击确定

       image

       要想查看这个代理类代码的文件,可以在解决方案资源管理器中单击“显示所有文件”,展开“服务引用”节点,打开 Reference.svcmap 节点,打开 Reference.cs 文件

       这个代理类包含有允许你触发相应 Web 服务调用的方法,并且负责那些繁重的琐碎任务(创建请求消息、在 HTTP 请求中发送此消息、得到相应、然后通知你的代码)

调用 WEB 服务

       在 Silverlight 页面中要使用这个代理类,不要忘记引入刚才命名的命名空间,本例的命名空间是:

using SilverlightApplication1.ServiceReference1;

       在 Silverlight 中,所有的 Web 服务调用都必须是异步的。这意味着你调用一个方法来开始调用(并发出请求)。这个方法以类似 MethodNameAsync() 这样的格式来命名。比如,Web 服务包含一个叫 GetServerTime() 的方法,你的代理类就需要提供一个名为 GetServerTimeAsync() 的方法,这个方法会立刻返回。

       当调用一个异步方法之后,代码可以继续执行其他任务,用户可以继续与该应用程序交互。当收到来自 Web 服务的响应时,代理就会触发一个事件,该事件类似 MethodNameCompleted 这样的格式命名。如 GetServerTimeCompleted,你可以通过事件处理程序对返回的结果做出处理。

       这种分成两段式的交互过程与普通的本地对象交互相比,将需要花费更多的工作来处理 Web 服务调用。但毕竟一个 HTTP 调用 WEB 服务有可能需要很长的时间,让用户长时间等待并不安全。微软对此加以限制,以确保你的代码不会给它们的平台带来坏名声。

       下面的代码演示按钮被单击时,如何调用前面提到过的 GetServerTime() 方法:

private void cmd_Click(object sender, RoutedEventArgs e)
{
    // Create the proxy.
    SilverlightTestServiceClient proxy = new SilverlightTestServiceClient();
 
    // Attach an event handler to the completed event.
    proxy.GetServerTimeCompleted += 
        new EventHandler<GetServerTimeCompletedEventArgs>(proxy_GetServerTimeCompleted);
 
    // Start the web service call.
    proxy.GetServerTimeAsync();
}

       为了得到想要的结果,需要处理 Completed 事件并且检查相应的 EventArgs 对象。当生成代理类时,VS 也会为每一个方法创建一个不同的 EventArgs 类。这些类唯一的区别是 Result 属性不同,这些结果的类型要与方法的返回值相匹配。

       第一次访问 Result 属性时,需要使用异常处理。这是因为如果 Web 服务调用失败,在这里会抛出错误。例如,找不到服务器,或者 Web 方法返回了一个错误,或者连接超时等等。

       下面是读取结果并将其显示在 TextBlock 上:

void proxy_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e)
{
    try
    {
        lblTime.Text = e.Result.ToLongTimeString();
    }
    catch (Exception err)
    {
        lblTime.Text = "Error contacting web service";
    }
}

image

       尽管 Web 服务调用是在后台线程中执行,但你不必担心 Completed 事件激活时的线程封送。这是因为 Web 服务代理确保了 Completed 事件将在用户界面线程上激活,允许你放心的访问页面上的控件

       默认情况下,1分钟之内没有收到响应,Web 服务代理就会放弃等待。你也可以在 Web 服务调用之前配置超时时间:

// Start the web service call.
proxy.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(30);
proxy.GetServerTimeAsync();

配置 Web 服务 URL

       当你添加服务引用时,自动生成的代码中就会包含 Web 服务 URL。因此,当你创建代理类的一个实例时,不必指定 URL。

       然而,这里有个潜在的问题。所有 Web 服务 URL 是绝对路径,相对路径是不允许的。如果你正在使用 VS 中的测试 Web 服务器,那么当测试 WEB 服务器选择了一个不同的端口时,就意味着稍后运行程序时会遇到麻烦,同样,当你将最终的应用程序部署到一个生产服务器上,你将不得不更新 URL。

       你可以通过重新生成服务引用来解决这个问题,但通常在代码中动态改变地址是更好的方法。要做到这一点,需要创建一个新的使用合适 URL 参数的 EndpointAddress 对象,并且在创建代理类实例的时候将其作为参数传递进去

       以下代码确保了 Web 服务调用始终工作,无论 VS 测试 Web 服务器选择什么端口号。注意,以下假设 Web 服务的名称是 SilverlightTestService.svc,且它被放入一个虚拟目录名为 SilverlightApplication1.Web 的网站里:

// Create the proxy.
SilverlightTestServiceClient proxy = new SilverlightTestServiceClient();
 
// Create a new URL for the SilverlightTestService.svc using the current port number.
proxy.Endpoint.Address = new System.ServiceModel.EndpointAddress("http://localhost:"
    + HtmlPage.Document.DocumentUri.Port
    + "/SilverlightApplication1.Web/SilverlightTestService.svc");

       使用类似上述的代码,你可以随时动态的更改 Web 服务的 URL ,使得你无论在哪里部署 Web 服务都非常方便,前提是 Web 服务和 Silverlight 应用程序在同一个 Web 文件夹内。

       本系列中,快速浏览了 Silverlight 最重要的特性。然而仍有很多特性限于篇幅而没有涉及,包括样式、控制面板、隔离存储以及数据绑定。若要更全面了解 Silverlight,可以参考专类书籍。例如 Pro Silverlight 3 in C# 2010(Apress,2009)

原文地址:https://www.cnblogs.com/SkySoot/p/2990391.html