Beginning Silverlight 4 in C#-数据访问和网络

Silverlight应用程序的数据访问与传统的应用程序有些区别。你需要搞清楚它的工作原理和它的局限性。这一章,你会看到为什么Silverlight的数据访问与众不同,同时研究Silverlight应用程序的数据访问机制。

Silverlight应用程序的数据访问

就像前面讨论的一样,RIAs消除了Windows-Based的智能客户端与Web-based应用程序的隔阂。当在RIAs这种类型的环境下时,数据访问和网络会令人迷惑。

在智能客户端里,应用程序总是能访问数据。它可以创建一个到数据库的连接,维护数据库的状态,同时保持连接。

另一方面,WEB应用程序是所谓的“伪会话”环境,意思是,在大部分情况下,是一个完全无状态和无连接的环境。客户端建立一个到服务端的请求,服务端处理请求和返回响应到客户端。响应发送完后,客户端和服务端的连接就会断开。同时服务器继续处理下一个请求。客户端和服务端之间没有维护连接和状态。

在Silverlight应用程序,我们增加了一个复杂的层。应用程序是在客户端的机器运行,仍然是无连接环境,因为它是寄宿在浏览器的。每一个请求都没有回发的概念,也不能创建一个到服务端的双向的数据处理请求。因此,数据访问被限制为几种选择。

另外,一个Silverlight应用程序有一系列的安全限制来保护保护应用程序的用户,以免应用程序获得太多的机器控制权。其中一个例子是,Silverlight应用程序只能访问隔离的存储区域来存储离线数据。它不能访问”沙箱“外的任何客户端的硬件。

那在Silverlight里有什么途径可以访问数据呢?如下:

Silverlight最普通的访问数据方式是Web服务,尤其是WCF服务。

Silverlight可以使用ADO.NET 数据服务访问数据,它是通过URI句法来访问数据的。

Silverlight 也有内置的Socket支持,它允许应用程序通过TCP Socket直接连接到服务器。

Silverlight默认支持JSON,也支持RSS2.0和Atom1.0。

这些方式中,这里会深入解析WCF服务,简单地尝试使用Sockets。

通过Web服务访问数据

这些服务可以是ASP.NET Web Service(ASMX),WCF服务或者是REST服务。

练习:使用WCF服务访问数据

这个练习修改自前面DataGrid的练习。不同的是这里会通过一个Web服务来获取数据。

看看下图可能有助回忆:

image

  1. 使用VS2010创建一个名为WCFService的Silverlight应用程序。
  2. 右击WCFService.Web,‘添加新项’就像前面一样添加一个名为StartingHands.cs的类,代码如下:
    public class StartingHands {
    
        public string Nickname { get; set; }
    
        public string Notes { get; set; }
    
        public string Card1 { get; set; }
    
        public string Card2 { get; set; }
    
    
    
        public static List<StartingHands> GetHands() {
    
            List<StartingHands> hands = new List<StartingHands>();
    
            hands.Add(new StartingHands() {
    
                Nickname = "Big Slick",
    
                Notes = "Also referred to as Anna Kournikova.",
    
                Card1 = "As",
    
                Card2 = "Ks"
    
            });
    省略。。。。。。 return hands; } }
  3. 接着创建一个WCF服务。在WCFService.Web中添加新项=》“启用了Silverlight的WCF服务”,名为StartingHandService.svc。

  4. 修改Dowork方法为GetHands,代码如下:

    [OperationContract]
    
    public List<StartingHands> GetHands() {
    
        return StartingHands.GetHands();
    
    }
  5. 回到WCFService项目,添加服务引用=》添加上面的WCF服务,命名为StartingHandService。

  6. 打开MainPage.xaml,把前面的XAMLCopy过来,它们是一样的,区别只是获取数据改为使用WCF服务。

  7. 打开MainPage.xaml.cs,添加如下带代码来调用WCF服务:

    public MainPage() {
    
        InitializeComponent();
    
    
    
        this.Loaded += (sender, e) =>
    
        {
    
            var service = new StartingHandServiceClient();
    
            service.GetHandsCompleted += (sender1, e1) => 
    
            {
    
                this.grdData.ItemsSource = e1.Result;
    
            };
    
            service.GetHandsAsync();
    
        };
    
    }
  8. 运行后可得到和上面一样的结果。

这个例子展示了使用VS提供的“启用了Silverlight的WCF服务”来访问远程数据。就如前面所说,这是Silverlight最普通的数据访问方式。

从其他域访问服务

前面那个例子里,WCF服务与Silverlight应用程序实在同一域的。如果要访问不同域的服务要怎么做呢?

实际上,作为最佳实践,你应该将服务和应用程序的域分离。即使服务和Silverlight应用程序都在你的控制范围内,你也应该分开不同的域处理。

如果你尝试直接在Silverlight里访问不同域的服务,你会发现是行不通的。这是因为除非在服务寄宿时允许它,默认Silverlight应用程序是不能调用其它域的服务的。Silverlight应用程序能不能访问某个确定的域,取决于在目标域的根目录的一个或两个文件:clientaccesspolicy.xml or crossdomain.xml。

首先,Silverlight会在域的根目录查找名为clientaccesspolicy.xml的文件。这是Silverlight客户端访问策略文件。如果你希望你发布的服务Silverlight应用程序能访问,就要使用这个特殊的文件,它提供了Silverlight应用程序访问策略权限的大部分选项。下面是一个简单的clientaccesspolicy.xml的例子:

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

    <cross-domain-access>

        <policy>

            <allow-from http-request-headers="*">

                <domain uri="*"/>

            </allow-from>

            <grant-to>

                <resource path="/" include-subpaths="true"/>

            </grant-to>

        </policy>

    </cross-domain-access>

</access-policy>

最重要的元素是<allow-from>和<grant-to>。<allow-from>元素定义了可以访问<grant-to>元素规定的资源中的那些域。

如果Silverlight在想尝试访问的服务的域的根目录下找不到clientaccesspolicy.xml,就会尝试找名为crossdomain.xml的文件。这是为Flash应用程序访问跨域服务的XML策略文件,Silverlight也支持这个文件。下面是简单的例子:

<?xml version="1.0"?>

<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

<cross-domain-policy>

    <allow-http-request-headers-from domain="*" headers="*"/>

</cross-domain-policy>

虽然Silverlight支持crossdomain.xml,但是使用clientaccesspolicy.xml才是最佳实践。

总结

在这一章,探讨了Silverlight应用程序通过WCF服务来访问数据,还有关于跨域访问策略文件问题。

你可能感兴趣的:(silverlight)