一步一步学Silverlight 2系列(17):数据与通信之ADO.NET Data Services

概述

Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ironpython,对JSON、Web Service、WCF以及Sockets的支持等一系列新的特性。《一步一步学Silverlight 2系列》文章将从Silverlight 2基础知识、数据与通信、自定义控件、动画、图形图像等几个方面带您快速进入Silverlight 2开发。

本文将简单介绍在Silverlight 2中如何调用ADO.NET Data Services。

准备知识

由于ADO.NET Data Services是在ASP.NET 3.5 Extensions中,所以在开始本文示例之前,首先要安装一下ASP.NET 3.5 Extensions最新版本,你可以从这里下载。安装完成后,在添加新项对话框中应该能够看到ADO.NET Data Service项:

TerryLee_Silverlight2_0077

ADO.NET Data Service允许应用程序把数据以服务的形式公开,这样我们就可以通过浏览器来直接访问数据,它支持开放的业界标准,如AtomPub和JSON。它支持标准的HTTP动作如POST、GET、PUT、DELETE,用来完成数据的创建、更新、删除和读取。ADO.NET Data Service的知识这里不再多说,大家可以去查看相关的资料。

简单示例

如果大家看了前面三篇文章的话,可能对于下面的这个界面已经很烦了,不过在本文我会仍然采用这个示例进行演示:)

TerryLee_Silverlight2_0065

建立完Silverlight 2项目之后,我们在Web项目中添加一个Post类:

public class Post
{
    public int Id { get; set; }

    public string Title { get; set; }

    public string Author { get; set; }
}

我们用Id作为Post的主键,这里需要添加对于Microsoft.Data.Web.dll程序集的引用,位于<盘符>\Program Files\Reference Assemblies\Microsoft\Framework\ASP.NET 3.5 Extensions下面,引入命名空间using Microsoft.Data.Web,并且为Id加上[DataWebKey]特性,最终完成后代码应该如下:

public class Post
{
    [DataWebKey]
    public int Id { get; set; }

    public string Title { get; set; }

    public string Author { get; set; }
}

再添加一个Blog类,它有一个返回类型为IQueryable<Post>的属性Posts:

public class Blog
{
    public Blog()
    {
        _post.Add(new Post { Id = 1, Title = "一步一步学Silverlight 2系列(13):数据与通信之WebRequest", Author = "TerryLee" });
        _post.Add(new Post { Id = 2, Title = "一步一步学Silverlight 2系列(12):数据与通信之WebClient", Author = "TerryLee" });
        _post.Add(new Post { Id = 3, Title = "一步一步学Silverlight 2系列(11):数据绑定", Author = "TerryLee" });
        _post.Add(new Post { Id = 4, Title = "一步一步学Silverlight 2系列(10):使用用户控件", Author = "TerryLee" });
        _post.Add(new Post { Id = 5, Title = "一步一步学Silverlight 2系列(9):使用控件模板", Author = "TerryLee" });
        _post.Add(new Post { Id = 6, Title = "一步一步学Silverlight 2系列(8):使用样式封装控件观感", Author = "TerryLee" });
    }

    List<Post> _post = new List<Post>();

    public IQueryable<Post> Posts
    {
        get { return _post.AsQueryable<Post>(); }
    }
}

添加一个ADO.NET Data Service,取名BlogDataService.svc:

TerryLee_Silverlight2_0077

实现服务,让它继承于泛型的WebDataService,并且设置访问权限。

public class BlogDataService : WebDataService<Blog>
{
    public static void InitializeService(IWebDataServiceConfiguration config)
    {
        config.SetResourceContainerAccessRule("*", ResourceContainerRights.AllRead);
    }
}

现在我们的服务端就完成了,现在我们可以在浏览器中访问BlogDataService.svc,应该可以看到如下界面:

TerryLee_Silverlight2_0078

现在还看不到所有的Posts,我们可以在地址栏中输入http://localhost:8081/BlogDataService.svc/Posts,浏览器会默认为Feed打开,可以查看源代码,将会看到所有内容,XML内容如下(只列出片段):

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://localhost:8081/BlogDataService.svc/" ......>
  <id>http://localhost:8081/BlogDataService.svc/Posts</id>
  <updated />
  <title>Posts</title>
  <link rel="self" href="Posts" title="Posts" />
  <entry adsm:type="TerryLee.SilverlightWithDataServiceDemoWeb.Post">
    <id>http://localhost:8081/BlogDataService.svc/Posts(1)</id>
    <updated />
    <title />
    <author>
      <name />
    </author>
    <link rel="edit" href="Posts(1)" title="Post" />
    <content type="application/xml">
      <ads:Id adsm:type="Int32">1</ads:Id>
      <ads:Title>一步一步学Silverlight 2系列(13):数据与通信之WebRequest</ads:Title>
      <ads:Author>TerryLee</ads:Author>
    </content>
  </entry>

如果要查看某一条文章的内容,可以输入http://localhost:8081/BlogDataService.svc/Posts(2)进行查看,如下图所示。

TerryLee_Silverlight2_0079

当然还可以进行其他的查询,使用filter和orderby等,如http://localhost:8081/BlogDataService.svc/Posts?$filter=Id eq 1&$orderby=Id,这里不在介绍。至此我们的数据服务端就算完成了。下面再实现客户端,XAML不再贴出来,大家可以参考前面的几篇文章,使用WebClient获取数据,返回的结果是一个XML文件:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    Uri uri = new Uri("http://localhost:8081/BlogDataService.svc/Posts");
    WebClient client = new WebClient();
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
    client.OpenReadAsync(uri);
}

void client_OpenReadCompleted(object sender,OpenReadCompletedEventArgs e)
{
    if (e.Error == null)
    {
        
    }
}

我们可以使用LINQ to XML进行数据的读取,在Silverlight项目中建立一个Post类,跟上面的Post类一样,然后使用LINQ to XML读取:

XmlReader reader = XmlReader.Create(e.Result);

XDocument postdoc = XDocument.Load(reader);

XNamespace xmlns = "http://www.w3.org/2005/Atom";
XNamespace ads = "http://schemas.microsoft.com/ado/2007/08/dataweb";

var posts = from x in postdoc.Descendants(xmlns + "entry")
            select new Post
            {
                Id = int.Parse(x.Descendants(ads + "Id").First().Value),
                Title = x.Descendants(ads + "Title").First().Value,
                Author = x.Descendants(ads + "Author").First().Value
            };

Posts.ItemsSource = posts;

完成的代码如下所示:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    Uri uri = new Uri("http://localhost:8081/BlogDataService.svc/Posts");
    WebClient client = new WebClient();
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
    client.OpenReadAsync(uri);
}

void client_OpenReadCompleted(object sender,OpenReadCompletedEventArgs e)
{
    if (e.Error == null)
    {
        XmlReader reader = XmlReader.Create(e.Result);

        XDocument postdoc = XDocument.Load(reader);

        XNamespace xmlns = "http://www.w3.org/2005/Atom";
        XNamespace ads = "http://schemas.microsoft.com/ado/2007/08/dataweb";

        var posts = from x in postdoc.Descendants(xmlns + "entry")
                    select new Post
                    {
                        Id = int.Parse(x.Descendants(ads + "Id").First().Value),
                        Title = x.Descendants(ads + "Title").First().Value,
                        Author = x.Descendants(ads + "Author").First().Value
                    };

        Posts.ItemsSource = posts;
    }
}

完整的示例就到这里了,运行后的结果与前面的一样。

TerryLee_Silverlight2_0065

结束语

本文简单介绍了在Silverlight 2调用ADO.NET Data Services,由于对ADO.NET Data Services了解不多,有错误的地方还请大家斧正,你可以从这里下载示例代码。

下一篇:一步一步学Silverlight 2系列(18):综合实例之RSS阅读器

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Tag标签: Silverlight
2
0
(请您对文章做出评价)
« 上一篇:一步一步学Silverlight 2系列(16):数据与通信之JSON
» 下一篇:一步一步学Silverlight 2系列(18):综合实例之RSS阅读器
posted @ 2008-03-10 18:34 TerryLee 阅读(13061) 评论(36)  编辑 收藏 网摘 所属分类: [03]  银光点亮世界

  回复  引用    
#1楼2008-03-10 18:50 | pwz[未注册用户]
感谢TerryLee的努力
Jesse Liberty,the Silverlight Geek,正在silverlight.net上发表一个《Silverlight教程系列》。目前已经发表了四篇,看上去也很不错:

教程0: 路线图

教程1: 控件

教程2: 数据绑定

教程3: 样式和模板

http://silverlight.net/learn/tutorials.aspx
如果有空能翻译一下也非常的好!!

  回复  引用  查看    
#2楼[楼主]2008-03-10 18:52 | TerryLee      
@pwz
我看到了Jesse Liberty写的那个系列,写的很详细:)

  回复  引用    
#3楼2008-03-10 19:12 | pwz[未注册用户]
是呀,我也非常盼望那个系列的文章的中文版!!!
  回复  引用    
#4楼2008-03-10 21:50 | 5254341[未注册用户]
TerryLee 同学太疯狂了。这么短时间内写出这么东西。
真是佩服呀!

  回复  引用  查看    
#5楼[楼主]2008-03-10 21:56 | TerryLee      
@5254341
小小的“疯狂”一把:)

  回复  引用    
#6楼2008-03-10 23:33 | jejwe[未注册用户]
建议TerryLee 也出个 ADO.NET Data Service简单教程。这个好像国内的教程文章还没有。看了你这个觉得很好用啊
  回复  引用  查看    
#7楼[楼主]2008-03-10 23:42 | TerryLee      
@jejwe
目前确实没有中文的教程,甚至很少有人关注,英文的资料也不多

要研究的东西太多了,有时间我可以写一些简单的,呵呵

  回复  引用  查看    
#8楼2008-03-10 23:51 | 阿布      
--引用--------------------------------------------------
TerryLee: @jejwe
目前确实没有中文的教程,甚至很少有人关注,英文的资料也不多

要研究的东西太多了,有时间我可以写一些简单的,呵呵
--------------------------------------------------------
算是MS的REST,也是未来的web发展的一个方向

是啊,新东西太多,要研究的也太多.



刚才在dzone看到一个
(NET runs on Linux, Mac OSX and FreeBSD )
Everybody knows about Mono, the .net for Linux. This is not about Mono.

http://www.cnblogs.com/jejwe/archive/2008/03/10/1099686.html

  回复  引用  查看    
#9楼[楼主]2008-03-11 08:36 | TerryLee      
@阿布
:)

  回复  引用  查看    
#10楼2008-10-31 16:29 | zhiyuan      
var posts = from x in postdoc.Descendants(String.Concat(xmlns, "entry"))
select new PostForDataService
{
Id = Int32.Parse(x.Descendants(String.Concat(ads, "Id")).First().Value),
Title = x.Descendants(String.Concat(ads, "Title")).First().Value,
Author = x.Descendants(String.Concat(ads, "Author")).First().Value,
};
Posts.ItemsSource = posts;

我如果这样写,用String.Concat()
为什么会报:

名称中不能包含“:”字符(十六进制值 0x3A)。"

TerryLee可以解释一下吗?

  回复  引用  查看    
#11楼2008-10-31 17:31 | zhiyuan      
DataService与WebDataService有什么区别?
  回复  引用    
#12楼2008-11-04 10:52 | stu[未注册用户]
[DataWebKey]这属性能不能用别的代替,找不到Microsoft.Data.Web.dll,我是用的这一个using System.Data.Services;,有类似的属性吗?谢谢
  回复  引用  查看    
#13楼[楼主]2008-11-05 09:27 | TerryLee      
@zhiyuan
在最新版中,ADO.NET Data Services可以直接在Silverlight通过添加引用来使用,就像使用WCF一样,无需再向上面这么麻烦

  回复  引用    
#14楼2008-11-17 15:41 | laurel[未注册用户]
怎么实现取sql的数据.
ASP.NET 3.5 Extensions 下载地址错了?
还是失效了.

  回复  引用  查看    
#15楼[楼主]2008-11-17 23:08 | TerryLee      
@laurel
现在在.NET Framework SP1中:)

  回复  引用  查看    
#16楼2008-11-18 11:13 | laurel's blog      
好,我装的是sp1,没找到 Microsoft.Data.Web.dll

  回复  引用    
#17楼2009-02-04 15:34 | 双宇[未注册用户]
博主好 一直在看你的文章 感觉学起来很容易上手 。最近遇到一个问题 我的webservice还有ADO.NET Data Service等和服务有关的项目在VS2008中调试时一切正常,但是发布在IIS上时服务就不能正常工作,无法从数据库中读取数据?

李兄能否帮我想想问题所在?万分感谢。

  回复  引用  查看    
#18楼2009-05-04 15:35 | 冰碟      
--引用--------------------------------------------------
TerryLee: @laurel
现在在.NET Framework SP1中:)
--------------------------------------------------------
我的也是同样的问题,找不到。我已经打了sp1的补丁。

  回复  引用  查看    
#19楼2009-05-04 15:51 | 冰碟      
李大哥,我还是找不到这个库Microsoft.Data.Web.dll。
能不能发我一份。

  回复  引用  查看    
#20楼2009-05-18 14:44 | 徐培华      
--引用--------------------------------------------------
冰碟: 李大哥,我还是找不到这个库Microsoft.Data.Web.dll。
能不能发我一份。
--------------------------------------------------------
我也找不到这个组件。

  回复  引用  查看    
#21楼[楼主]2009-05-19 16:36 | TerryLee      
@徐培华
安装.NET Framework 3.5 SP1了就有,ADO.NET Data Service已经在SP1中发布了。不过命名空间有所变化。

  回复  引用  查看    
#22楼2009-05-20 08:19 | 徐培华      
VS2008 SP1 算不算楼主说的那个framework 3.5 sp1?????
莫非还要单独去下载??

  回复  引用  查看    
#23楼[楼主]2009-05-22 13:43 | TerryLee      
@徐培华
在SP1中已经包含了。

  回复  引用  查看    
#24楼2009-06-01 10:28 | 姜立军      
李兄你好,我用ADO.Net连接Oracle数据库,报System.Data.Services.Client.DataServiceRequestException: 处理此请求时出错。
在网上查查了,说是给的权限不足引起的,可是我的权限已经设置为ALL了,这是怎么回事,是不是可以在其他地方设置权限了?谢谢

  回复  引用  查看    
#25楼2009-06-23 22:45 | 姜立军      
李兄你好,上次的问题已经解决,我在把ADO.NET Data Services 服务部署到IIS上的时候,报“IIS 指定了身份验证方案“IntegratedWindowsAuthentication, Anonymous”,但绑定仅支持一种身份验证的规范。有效的身份验证方案为摘要、协商、NTLM、基本或匿名。请更改 IIS 设置,以便仅使用单一的身份验证方案。”的错误,请问有何解决方案,在网上找了一些都没有解决,这个问题困扰了我好久也没有解决,请李兄帮忙解决一下,先谢谢了!!!
  回复  引用    
#26楼2009-07-24 11:43 | sunnfy[未注册用户]
楼主,辛苦了,我的vs2008装了sp1,怎么找不到Microsoft.Data.Web.dll ,能告诉我如何获取吗?先谢谢了!
  回复  引用  查看    
#27楼2009-07-28 10:53 | 惜分飞      
http://kb.cnblogs.com/page/43963/?page=1
建议大家先多下这个吧

  回复  引用    
#28楼2009-08-03 10:31 | aking11[未注册用户]
@徐培华
在最新版本儿framework中,DataWebKey已经被替换成了DataServiceKey,添加引用:using System.Data.Services.Common;位于 System.Data.Services.Common 这个命名空间下,在具体使用时
[DataServiceKey("FirstName")]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}

  回复  引用  查看    
#29楼2009-08-09 19:54 | Stiven      
C# 3.0 Unleashed: With the .NET Framework 3.5

Chapter 23
From Beta to RTM Changes to Make Throughout Chapter (including code)
Change WebDataService to DataService

Change IWebDataServiceConfiguration to IDataServiceConfiguration

Change SetResourceContainerAccessRule to SetEntitySetAccessRule

Change ResourceContainerRights to EntitySetRights

Change Microsoft.Data.WebClient to System.Data.Services.Client.dll