silverlight服务器:数据点:从 Silverlight 2 观望云服务

  本文举例源代码或素材下载

  本专栏基于 Silverlight 2 预发布版本文中所有信息均有可能发生变更

  数据点:从 Silverlight 2 观望云服务目录

  在 Silverlight 2 中如何处理 Web 服务?

  如何将数据从服务传递到 Silverlight 2?

  如何从 ASMX Web 服务使用数据?

  如何从 WCF Web 服务使用数据?

  如何从 REST Web 服务接收数据?

  如何查询 XML?

  当访问第 3方 Web 服务时是否需要担心跨域策略?

  使用 Silverlight 开发人员经常给人种虚幻感但这能责怪他们吗?从各种 Web 服务中为富 Internet 应用 (RIA) 获取数据正成为主流趋势Silverlight 应用可以和 ASMX Web 服务、Windows® Communication Foundation (WCF) Web 服务、具象状态传输 (REST) 服务和传统 XML (POX) 服务进行通信无论这些服务是由第 3方提供服务还是 Silverlight 应用所在服务器上托管自定义服务Silverlight 都能够请求数据、使用数据并可在 Silverlight 客户端应用和此类 Web 服务的间来回传递数据

  根据向我提出问题分析开发人员们明显希望了解更多有关从 Silverlight 2 应用服务、使用 WCF、ASMX 和 REST 服务的间差别以及如何使用这些服务提供数据方面内容在本期“数据点”中我将回答其中部分问题并演示如何处理数据服务

  第 3方 Web 服务不胜枚举它们内容包罗万象从访问其 API 到存储客户端特定数据和自定义数据尽在其中我将讨论如何在 Silverlight 应用和服务云的间使用和传递数据此外我还将介绍如何使用几个 XML 解析库使用这些数据例如可以打开并迭代整个 XML 文档或者使用 LINQ to XML 查询 XML类似 Flickr、Amazon、Twitter 和 Live Search 的类服务都提供能使用各种 Web 服务技术和的进行通信 API我将在这里讨论其中部分 API并介绍如何使用基于 REST 和 SOAP 服务和的通信可从MSDN 杂志网站WebSite下载此专栏中所有举例(同时提供 C# 和 Visual Basic 版本)

  在 Silverlight 2 中如何处理 Web 服务?

  首先讨论这个问题非常合适通过它可以了解为什么如此众多开发人员热衷于使用 Silverlight 2 和 Web 服务进行交互Silverlight 1.x 无法利用 Microsoft .NET Framework 支持代码也没有任何 .NET Control控件Silverlight 2 引入了许多完整功能消除了以前版本中限制Silverlight 2 使您能够以 C# 或 Visual Basic 编写代码并充分利用您现有 .NET CLR 经验尽管 Silverlight 中包括库只是完整 .NET 库个子集但 Silverlight 2 功能却很全面例如可以从 Silverlight 访问 WebClient 和 HttpWebRequest 类并可通过 URI 和基于 Web 服务进行交互随后可以利用 XmlReader 对象或通过 LINQ to XML 使用这些数据

  Silverlight 2 中添加了大量用于在服务的间传递数据功能以下是 Silverlight 2 中全新添加功能:

  可以通过代理类访问基于 SOAP Web 服务

  可以访问基于 REST Web 服务

  可以访问 ADO.NET 数据服务(种允许进行远程 LINQ 查询且基于 REST 服务)

  可以使用 JavaScript Object Notation (JSON) 和 XML 从 Web 服务中检索结果

  通过 WCF(使用服务器推送)支持双工通信

  可以使用 clientaccesspolicy.xml 文件或 crossdo.xml 文件支持跨域访问

  可以使用 HTTP 和套接字提供跨域网络支持

  异步化 Web 服务

  如何将数据从服务传递到 Silverlight 2?

  图 1 显示了 Silverlight 2 能够访问几种服务类型数据可以在 Silverlight 2 和这些服务的间以 XML、JSON 或标量值形式进行传递基于 SOAP 服务还允许自我描述同样也允许对其所公开数据进行描述Silverlight 2 客户端可以通过服务代理从基于 SOAP 服务访问数据这些服务代理可以为公开类生成类描述

  数据点:从 Silverlight 2 观望云服务   图 1 从 Silverlight 访问服务

  基于 SOAP 服务可以进行自我描述因此 Silverlight 2 客户端应用能够使用任何公开实体和服务来回传递数据ASMX Web 服务和 WCF Web 服务都允许实体作为其合约部分包含在客户端引用中客户端引用在客户端上生成代理类其中包含公开类定义和服务思路方法(所有服务思路方法都转化为对 Silverlight 2 客户端异步)

  不能自我描述服务(例如 POX 和基于 REST 服务)允许客户端应用其服务思路方法并以标量格式(或者是 XML/JSON)检索数据这些类型服务不公开 Web 服务描述语言 (WSDL)因此客户端应用不能为其生成代理类此类服务需要通过 WebClient 或 HttpWebRequest 这样类并使用 URI 进行查询

  如何从 ASMX Web 服务使用数据?

  类似于 ASMX 服务基于 SOAP WCF Web 服务可以通过 WSDL 进行自我描述如果客户端添加对此类服务应用它将生成服务客户端代理从而允许客户端以本机形式(也就是类)随同服务传递数据例如可以从基于 SOAP Web 服务(ASMX 或 WCF)向 Silverlight 2 客户端返回 Dog 实体Silverlight 2 客户端可以随后创建 Dog 类例子通过在 ASMX Web 服务中使用 WebMethod 属性修饰公共服务思路方法并使用 WebService 属性修饰 ASMX Web 服务类向客户端公开思路方法图 2 以 C# 为例对此做出了介绍说明

  数据点:从 Silverlight 2 观望云服务图 2 在 C# 中从 Web 服务返回实体

[WebService(Namespace = "http://www.microsoft.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[.ComponentModel.ToolboxItem(false)]
public TestService : .Web.Services.WebService {
 [WebMethod]
 public List<Dog> GetDogList {
  List<Dog> { Dog {Name = "Spot", Age = 10},    Dog {Name = "Kadi", Age = 13}};
 }
}
[Serializable]
public Dog {
 public Name { get; ; }
 public Age { get; ; }
}


  该举例显示 Silverlight 2 客户端应用中以 .NET 为目标代码它可以生成 SOAP 服务代理事件处理将分配给 GetDogListCompleted 事件随后异步该服务所有从 Silverlight 2 中对 Web 服务都采用异步以便防止服务和 UI 线程绑定并冻结用户以下是接收结果(实体类型)事件处理:

TestServiceSoapClient proxy = TestServiceSoapClient;
proxy.GetDogListCompleted   EventHandler<GetDogListCompletedEventArgs>(proxy_ GetDogListCompleted);
proxy.GetDogListAsync;


  下面是接收实体 C# 代码:

  数据点:从 Silverlight 2 观望云服务

void proxy_GetDogListCompleted(object sender, 
 GetDogListCompletedEventArgs e)
{
 Dog list = e.Result;
}


  如何从 WCF Web 服务使用数据?

  类似于 ASMX Web 服务WCF Web 服务也能通过 WSDL 进行自我描述WCF Web 服务可以使用系列属性公开其服务和传递数据这表示客户端应用能够引用 WCF Web 服务并生成代理类以便和服务及其公开数据合约进行交互

  WCF 将数据合约定义为任何可以从 WCF Web 服务返回自定义 .NET 类型这些类型使用 DataContract 属性进行修饰属性必须使用 DataMember 属性进行修饰图 3 显示了采用适当属性进行修饰举例类

  数据点:从 Silverlight 2 观望云服务图 3 为 WCF 准备数据

[DataContract]
public Employee {
  _employeeID;
  _firstName;
  _lastName;
  _title;
 DateTime _hireDate;
  _photo;
 [DataMember]
 public EmployeeID {
  get { _employeeID; }
   { _employeeID = value; }
 }
 [DataMember]
 public FirstName {
  get { _firstName; }
   {_firstName = value; }
 }
 [DataMember]
 public LastName {
  get { _lastName; }
   { _lastName = value; }
 }
}


  使用 DataContract 和 DataMember 属性为 WCF Web 服务定义好数据格式的后必须设置服务及其服务思路方法服务使用 ServiceContract 属性进行修饰其思路方法使用 OperationContract 属性修饰如果需要服务还可以实现接口在这种情况下将使用属性修饰该接口(而不是服务类)及其接口思路方法以下是使用这些属性修饰 IEmployeeService 及其成员:

  [ServiceContract(Namespace = "")]
  public erface IEmployeeService
  {
  [OperationContract]
  List<Employee> FindEmployees;
  }


  请注意:Silverlight 2 应用仅可和使用 basicHttpBinding 且基于 SOAP WCF 服务配用

  Silverlight 2 客户端应用可以添加对此服务引用从而创建代理类随后可以异步该服务(类似于 ASMX Web 服务)并且处理可以帮助捕获结果实现代理和完成事件处理代码使用完全相同格式如前面 ASMX Web 服务所示返回 List<Employee> 类型数据后必要时可以通过服务思路方法迭代、数据绑定、修改和传回实体

  如何从 REST Web 服务接收数据?

  可以使用带参数查询串通过 URI REST 服务可以使用 WebClient 类或 HttpWebRequest 从 Silverlight 2 虽然通过 WebClient 进行更为简单但 HttpWebRequest 能够提供对请求方式更多控制而且WebClient 在 UI 线程中返回而 HttWebRequest 则在后台线程中返回HttpWebRequest 回调必须使用 Dispatcher 才能和 UI 交互下面代码显示了从 Digg 服务中检索最新文章 .Net.WebClient:

baseUri = "http://services.digg.com/stories/topic";
topic = txtTopic.Text;
appKey = "http%3A%2F%2Fwww.microsoft.com";
count = .Parse(txtTopicCount.Text);
url = String.Format("{0}/{1}?appkey={2}&count={3}", baseUri, topic, appKey, count);
WebClient svc = WebClient;
svc.DownloadStringAsync( Uri(url));


  从 WebClient 返回数据是原始 XML稍后可对该数据进行解析或查询如果 REST 服务带有参数则它们可以作为查询部分传递

  如何查询 XML?

  当基于 REST 或 POX 服务时它将返回 XML 形式数据(REST 服务还可返回 JSON 形式数据)随后可以使用许多 XML 解析库对该 XML 进行解析但也可以使用 LINQ to XML 查询 XML这种思路方法提供了更为丰富查询接口可以在无需借助于迭代整个复杂 XML 层次关系情况下从 XML 结构中提取数据

  您刚才所见举例中 REST 服务从 Digg 服务中返回显示最新文章原始 XML随后可以使用 XML 库解析该 XML或者使用 LINQ to XML 对其进行查询如图 4 所示XDocument 类 Parse 思路方法可以使用从前面所示 REST 服务中得到 XML然后可以使用 LINQ to XML 查询该 XML图 4 中所示代码显示了用于查询图 5 中所示 XML LINQ to XML 语法

  数据点:从 Silverlight 2 观望云服务图 4 查询 Digg 数据 LINQ to XML

XDocument xml = XDocument.Parse(rawXml);
var storiesQuery = from story in xml.Descendants("story")
 select DiggStory
  {
    Id = ()story.Attribute("id"),
    Title = (()story.Element("title")).Trim,
    Description = (()story.Element("description")).Trim,
    ThumbNail =
     (story.Element("thumbnail") null
       ? .Empty
       : story.Element("thumbnail").Attribute("src").Value),
    Link = Uri(()story.Attribute("link")),
    DiggCount = ()story.Attribute("diggs")
  };


  数据点:从 Silverlight 2 观望云服务图 5 Digg XML 响应

<?xml version="1.0" encoding="utf-8" ?>
<stories timestamp="1222547017" min_date="1219955010" total="2541"
                         off="0" count="10">
 <story link="http://s.msn.com.us/2/hi/technology/7540282.stm"  
    submit_date="1222545893" diggs="1" id="8725656" comments="0"
    href="http://digg.com/microsoft/Microsoft_releases_SQL_Server_
    2005_recently" status="upcoming" media="s">
  <description>Microsoft has released SQL Server 2005 recently
    as an upgrade to the popular SQL Server database.</description>
  <title>Microsoft releases SQL Server 2005</title>
  <user name="D3a1i0" icon="http://digg.com/img/udl.png"
   registered="1104422772" profileviews="5616" />
  <topic name="Microsoft" _name="microsoft" />
  <container name="Technology" _name="technology" />
  <thumbnail originalwidth="226" originalheight="170" contentType=
   "image/jpeg" src="http://digg.com/microsoft/Microsoft_releases_SQL_
   Server_2005_recently/t.jpg" width="80" height="80" />
 </story>
 <story link="http://navigatetrends.blogspot.com/2008/09/microsofts-
   virtual-receptionist.html" submit_date="1222545326" diggs="1"
   id="8725560" comments="0" href="http://digg.com/microsoft/
   Microsoft_s_virtual_receptionist" status="upcoming" media="videos">
  <description>Microsoft's virtual receptionist</description>
  <title>Microsoft's virtual receptionist</title>
  <user name="billarunk" icon="http://digg.com/img/udl.png"
   registered="1216563445" profileviews="341" fullname="bill.arunk"
  />
  <topic name="Microsoft" _name="microsoft" />
  <container name="Technology" _name="technology" />
  <thumbnail originalwidth="400" originalheight="254" contentType="image/
   jpeg" src="http://digg.com/microsoft/Microsoft_s_virtual_
   receptionist/t.jpg" width="80" height="80" />
 </story>
...
...
</stories>


  该查询从 stories/story 层次开始并查询所有文章元素虽然没有为该 XML 指定命名空间但我保留了命名空间变量 (ns) 以便介绍说明在结果需要引用命名空间情况下如何为所有 XML 路径添加前缀操作文章元素工作通过使用 XDocument 例子 Descendants 思路方法完成文章元素属性可以使用文章变量及其 Element 思路方法检索例如下面代码行从文章元素中获取标题元素并将其赋给名为 Title 属性:

  数据点:从 Silverlight 2 观望云服务

Title = (()story.Element("title")).Trim

  LINQ to XML 查询可以通过反射或类结构返回结果图 4 中所示代码创建了 DiggStory 类以便存储从 XML 数据中检索到每个状态元素结果为简单起见开发人员定义 DiggStory 类中所有属性都被定义为如果需要LINQ to XML 还可以包含类似排序或筛选标准的类其它条件

  通过使用 LINQ to XML 查询和解析来自 REST 或 POX 服务 XML 数据开发人员能够充分利用其在 LINQ 方面其他知识各种形式的间语法非常相似或许使用 LINQ to XML 解析数据最大优势在于强大数据查询功能和简便性无需在嵌套 foreach 循环中迭代所有元素

  当访问第 3方 Web 服务时是否需要担心跨域策略?

  当 Silverlight 2 应用 Web 服务时会在 Web 服务所在服务器检查跨域策略文件从而排除该当 Silverlight 应用和 Web 服务处于区别域时需要完成此检查例如图 6 中显示位于 Web 服务器 johnpapa.net Silverlight 2 应用可以同样处于 johnpapa.net 域中 Web 服务它们位于相同但如果处于 johnpapa.net 域中 Silverlight 2 客户端想要处于 microsoft.com 域中 Web 服务则 Silverlight 2 将会进行检查以确保 microsoft.com 中存在跨域策略文件且允许此类

  数据点:从 Silverlight 2 观望云服务   图 6 跨域检查

  有关跨域策略更多信息请参阅我在 2008 年 9 月专栏“使用 Silverlight 2 和 WCF 构建服务驱动应用在该专栏中我讨论过文件格式及策略工作方式

  无论针对是 WCF Web 服务、基于 REST 服务还是任何其它类型 Web 服务Silverlight 2 仅在目标 Web 服务器通过其跨域策略文件允许情况下才能完成这操作以前面所用代码为例

  数据点:从 Silverlight 2 观望云服务

baseUri = "http://services.digg.com/stories/topic";
topic = txtTopic.Text;
appKey = "http%3A%2F%2Fwww.microsoft.com";
count = .Parse(txtTopicCount.Text);
url = String.Format("{0}/{1}?appkey={2}&count={3}", baseUri, 
 topic, appKey, count);
WebClient svc = WebClient;
svc.DownloadStringAsync( Uri(url));


   Digg Web 服务以访问最新文章Digg 包含使用 Flash 格式跨域策略文件该文件位于 http://services.digg.com/crossdo.xml

  编写本文时该 Digg 跨域文件内容如下所示:

  数据点:从 Silverlight 2 观望云服务

Tags:  silverlight2是什么 silverlight2 silverlight.2.0 silverlight服务器

延伸阅读

最新评论

发表评论