一步一步学Silverlight 2系列(14):数据与通信之WCF

概述

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中如何与WCF进行通信。

简单示例

在本示例中,我们将通过WCF来获取一个最新随笔的列表,在Silverlight中显示出来,最终完后效果如下所示。

TerryLee_Silverlight2_0065

先定义一个数据契约:

[DataContract]
public class Post
{
    public Post(int id,string title,string author)
    {
        this.Id = id;
        this.Title = title;
        this.Author = author;
    }

    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public string Author { get; set; }
}

在Web项目中添加一个WCF Service文件,命名为Blog.svc

TerryLee_Silverlight2_0063

定义服务契约:

[ServiceContract]
public interface IBlog
{
    [OperationContract]
    Post[] GetPosts();
}

实现服务,这里可以是从数据库或者其他数据源读取,为了演示方便,我们直接初始化一个集合:

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

        return posts.ToArray();
    }
}

修改Web.config中的服务配置,这里使用basicHttpBinding绑定,并且开启httpGetEnabled,以便后面我们可以在浏览器中查看服务:

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="TerryLee.SilverlightDemo27Web.BlogBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service behaviorConfiguration="TerryLee.SilverlightDemo27Web.BlogBehavior"
            name="TerryLee.SilverlightDemo27Web.Blog">
            <endpoint address="" binding="basicHttpBinding" contract="TerryLee.SilverlightDemo27Web.IBlog">
            </endpoint>
        </service>
    </services>
</system.serviceModel>

设置一下Web应用程序的端口号为固定端口52424,在浏览器中输入http://localhost:52424/Blog.svc,看看服务是否正常:

TerryLee_Silverlight2_0064

好了,现在服务端我们就实现完成了。现在编写界面展示部分,XAML如下:

<Grid Background="#46461F">
    <Grid.RowDefinitions>
        <RowDefinition Height="40"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Border Grid.Row="0" Grid.Column="0" CornerRadius="15"
            Width="240" Height="36" Background="Orange"
            Margin="20 0 0 0" HorizontalAlignment="Left">
        <TextBlock Text="最新随笔" Foreground="White"
                   HorizontalAlignment="Left" VerticalAlignment="Center"
                   Margin="20 0 0 0"></TextBlock>
    </Border>
    <ListBox x:Name="Posts" Grid.Row="1" Margin="40 10 10 10">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Id}" Height="40" Foreground="Red"></TextBlock>
                    <TextBlock Text="{Binding Title}" Height="40"></TextBlock>
                    <TextBlock Text="{Binding Author}" Height="40" Foreground="Orange"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

在Silverlight项目中添加服务引用,输入地址http://localhost:52424/Blog.svc,输入命名空间BlogService。

TerryLee_Silverlight2_0066

添加完成后,我们可以在对象浏览器中浏览一下生成的客户端对象:

TerryLee_Silverlight2_0067

当然大家也可以手工去编写客户端的代码,请参考WCF的相关内容,这里不再赘述。下面编写调用服务并获取数据,这里仍然是采用异步模式,由于在WCF服务的配置中我们采取了BasicHttpBinding,客户端也要采用BasicHttpBinding。我们需要注册GetPostsCompleted事件处理方法,以便完成后回调,同时调用GetPostsAsync()方法获取数据。完整的代码如下所示:

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        Binding binding = new BasicHttpBinding();
        EndpointAddress endPoint = new EndpointAddress(
                "http://localhost:52424/Blog.svc");

        BlogClient client = new BlogClient(binding, endPoint);
        client.GetPostsCompleted += new EventHandler<GetPostsCompletedEventArgs>(client_GetPostsCompleted);
        client.GetPostsAsync();
    }

    void client_GetPostsCompleted(object sender, GetPostsCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            Posts.ItemsSource = e.Result;
        }
    }
}

至此,一个完整的在Silverlight 2中调用WCF的示例就完成了,运行后效果如下:

TerryLee_Silverlight2_0065 

结束语

本文简单演示了在Silverlight 2中如何与WCF进行通信,你可以从这里下载示例代码。

下一篇:一步一步学Silverlight 2系列(15):数据与通信之ASMX

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Tag标签: Silverlight,XAML
posted @ 2008-03-09 21:41 TerryLee 阅读(8607) 评论(49)  编辑 收藏 所属分类: Silverlight

  回复  引用  查看    
#1楼 2008-03-09 21:43 | 侯垒      
博主的写作速度真是太快了.佩服佩服.
  回复  引用  查看    
#2楼 [楼主]2008-03-09 21:45 | TerryLee      
@侯垒
呵呵,周末有空就多写点,顺便也学习一下:)
  回复  引用  查看    
#3楼 2008-03-09 21:47 | Justin      
速度是够快的,佩服!
可否分享一下是用了什么学习方法,学习了哪些资源,或者是那本书?这么快!
  回复  引用  查看    
#4楼 [楼主]2008-03-09 21:49 | TerryLee      
@Justin
Silverlight 2刚出来,似乎还没有相关的书吧:)

参考SDK和http://silverlight.net/Learn/
  回复  引用  查看    
#5楼 2008-03-09 22:20 | 梦里花落知多少      
我的机器跑VS2008实在是费劲啊,又改回2005了:(

  回复  引用  查看    
#6楼 2008-03-09 22:22 | Cat Chen      
不错的系列,期待~
  回复  引用  查看    
#7楼 [楼主]2008-03-09 22:22 | TerryLee      
@梦里花落知多少
不装2008,暂时就体验不到Silverlight 2了哦:)
  回复  引用  查看    
#8楼 [楼主]2008-03-09 22:23 | TerryLee      
@Cat Chen
多谢支持:)
  回复  引用  查看    
#9楼 2008-03-10 08:59 | 木野狐(Neil Chen)      
还不懂 wcf。学习一下。
  回复  引用    
#10楼 2008-03-10 10:45 | hlink [未注册用户]
楼主真是.net和silverlight的骨灰级狂热者啊!周六日都不休息发布这么多牛X的文章,服了!
  回复  引用    
#11楼 2008-03-10 10:49 | 戏梦_wxf [未注册用户]
我想向博主请教一下,在silverlight1.0和1.1中,我可以通过initparam,和contex向silverlight传递字符串与对象。在silverlight2.0中如何实现呢?
  回复  引用    
#12楼 2008-03-10 13:59 | slici [未注册用户]
感同身受
  回复  引用  查看    
#13楼 [楼主]2008-03-10 14:27 | TerryLee      
@木野狐(Neil Chen)
呵呵,张逸翻译的那本书不错,可以看一下:)
  回复  引用  查看    
#14楼 [楼主]2008-03-10 14:28 | TerryLee      
@hlink
呵呵,谢谢,Silverlight 2确实功能很强,就多看了一些:)
  回复  引用  查看    
#15楼 [楼主]2008-03-10 14:30 | TerryLee      
@戏梦_wxf
这块我还不了解,我这几天看一下再回答:)
  回复  引用  查看    
#16楼 [楼主]2008-03-10 14:30 | TerryLee      
@slici
:)
  回复  引用    
#17楼 2008-03-14 10:36 | huson [未注册用户]
为什么我一改变WCF Service的名字,service就不好用了?Web.Config里面相应的service name也修改了啊!

谢谢
  回复  引用  查看    
#18楼 [楼主]2008-03-14 22:55 | TerryLee      
@huson
估计是哪儿没有修改完,应该是没有问题的,Web.config、还有.svc文件等都检查一遍吧:)
  回复  引用    
#19楼 2008-03-19 10:03 | hhhh [未注册用户]
添加服务引用前都是对的,添加后就会报错。

  回复  引用  查看    
#20楼 [楼主]2008-03-19 10:09 | TerryLee      
@hhhh
你下载文章中提供的示例代码,运行试一下。
  回复  引用    
#21楼 2008-03-19 10:14 | hhhh [未注册用户]
就是配置好webconfig以后,然后测试了wcf也是正确的,然后在sl项目中导入服务就会报错
  回复  引用    
#22楼 2008-03-19 10:19 | hhhh [未注册用户]
还想请教个问题,就是我看你教程中设置了fontfamily是微软雅黑,我设置了以后出来的字体怎么还是不变的?
  回复  引用  查看    
#23楼 [楼主]2008-03-19 11:05 | TerryLee      
@hhhh
那这个问题我就不清楚了,我这儿没有出现过类似的问题

可能是机器上没有装微软雅黑字体
  回复  引用    
#24楼 2008-03-21 12:13 | ondogdog [未注册用户]
运行出错“System.ServiceModel.ProtocolException”,在Referenec.cs的返回值的时候,怎样解决呢?
  回复  引用  查看    
#25楼 [楼主]2008-03-21 22:14 | TerryLee      
@ondogdog
我也不太清楚这个错误
  回复  引用  查看    
#26楼 2008-04-28 11:35 | 镜涛      
学习!
  回复  引用  查看    
#27楼 2008-05-06 23:34 | 傻样精英      
你好,看到了你的文章我也做了一个wcf和silverligth的练习,但是用silverlight调用的时候,报错如下:
operation is not valid due to the current state of the object

怀疑是endpoint没找到,请问下什么原因啊?程序我用邮件发给你了,不知道收到没有
  回复  引用    
#28楼 2008-07-08 22:58 | botsing [未注册用户]
我的是silverlight beta2的,为什么会出现
The remote server returned an unexpected response: (404) Not Found.这样的错误.
这个问题有没有解决方法呢?
  回复  引用  查看    
#29楼 [楼主]2008-07-09 09:49 | TerryLee      
@botsing
很可能是跨域的问题造成的。
  回复  引用    
#30楼 2008-07-09 22:28 | botsing [未注册用户]
@TerryLee
嗯,应该是这个问题,那有没有解决方法啊,网上找的基本上都是把wcf发不到iis上之后的办法,在vs2008中调试时有没有解决方法,还是只能发布到iis中才能用?
  回复  引用    
#31楼 2008-07-12 22:32 | ooxxxxxxxxx [未注册用户]
@TerryLee

你好,我下载您的包运行,结果完全OK。

不过,当然在这个解决方案内新建一个网站(端口8888)。然后将Sliverlight附加到此网站中,通过此站访问端口:52424这个站上的svc。

这时候列表中无法显示内容。但是我在52424网站根目录,分别添加了clientaccesspolicy.xml和crossdomain.xml测试。结果还是出不来。

我要怎么做呢?

谢谢。
  回复  引用    
#32楼 2008-07-13 23:48 | botsing [未注册用户]
终于发现错在哪了,忘了改成basicHttpBinding绑定了,郁闷
  回复  引用  查看    
#33楼 [楼主]2008-07-13 23:52 | TerryLee      
@botsing
Silverlight中只支持basicHttpBinding绑定
  回复  引用    
#34楼 2008-07-15 21:54 | botsing [未注册用户]
@TerryLee
嗯,现在知道了,谢谢楼主
  回复  引用  查看    
#35楼 2008-07-16 08:04 | 杰仔      
void client_GetPostsCompleted(object sender, GetPostsCompletedEventArgs e)


GetPostsCompletedEventArgs怎么我这里提示缺少引用,下载你的源码也一样的
  回复  引用  查看    
#36楼 [楼主]2008-07-21 10:26 | TerryLee      
@杰仔
重新添加一下引用再看看,另外,该示例在Beta 1下的,注意版本问题。
  回复  引用    
#37楼 2008-07-22 20:43 | MeteorCui [未注册用户]
搞不懂, Silverlight2 里怎么没有System.Data.Linq的命名空间
  回复  引用  查看    
#38楼 [楼主]2008-07-22 23:46 | TerryLee      
@MeteorCui
为什么Silverlight 2中要有System.Data.Linq命名空间呢?我说过很多次了,Silverlight是一种客户端技术,它不可以直接访问数据库,所以System.Data.Linq就没有必要了。
  回复  引用    
#39楼 2008-08-05 09:45 | 吕不韦 [未注册用户]
不能访问库,应该可以访问xml了吧,用xml也可以实现动态更新啊
  回复  引用  查看    
#40楼 [楼主]2008-08-06 13:25 | TerryLee      
@吕不韦
请问这个XML文件在哪儿?客户端 还是 服务端?
  回复  引用  查看    
#41楼 2008-09-28 11:49 | SnailFly      
The remote server returned an unexpected response: (404) Not Found.我也出现了这样的错误,但我的是basicHttpBinding绑定,这个问题有没有什么好的解决方法啊?


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-10 18:30 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接:

历史上的今天:
2006-03-09 重载还是覆写?