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

概述

Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ironpython,对JSON、Web Service、WCF以及Sockets的支持等一系列新的特性。《一步一步学Silverlight 2系列》文章带您快速进入Silverlight 2开发。

本文将介绍如何在Silverlight 2中使用Web Client进行通信。

简单示例

编写一个简单的示例,在该示例中,选择一本书籍之后,我们通过Web Client去查询书籍的价格,并显示出来,最终的效果如下:

TerryLee_Silverlight2_0059

编写界面布局,XAML如下:

<Grid Background="#46461F">
    <Grid.RowDefinitions>
        <RowDefinition Height="40"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="40"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Border Grid.Row="0" Grid.Column="0" CornerRadius="15"
            Width="240" Height="36"
            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="Books" Grid.Row="1" Margin="40 10 10 10"
             SelectionChanged="Books_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Name}" Height="32"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Border Grid.Row="2" Grid.Column="0" CornerRadius="15"
            Width="240" Height="36" Background="Orange"
            Margin="20 0 0 0" HorizontalAlignment="Left">
        <TextBlock x:Name="lblPrice" Text="价格:" Foreground="White"
                   HorizontalAlignment="Left" VerticalAlignment="Center"
                   Margin="20 0 0 0"></TextBlock>
    </Border>
</Grid>

为了模拟查询价格,我们编写一个HttpHandler,接收书籍的No,并返回价格:

public class BookHandler : IHttpHandler
{
    public static readonly string[] PriceList = new string[] { 
        "66.00",
        "78.30",
        "56.50",
        "28.80",
        "77.00"
    };
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write(PriceList[Int32.Parse(context.Request.QueryString["No"])]);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

在界面加载时绑定书籍列表,关于数据绑定可以参考一步一步学Silverlight 2系列(11):数据绑定

void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    List<Book> books = new List<Book>() { 
        new Book("Professional ASP.NET 3.5"),
        new Book("ASP.NET AJAX In Action"),
        new Book("Silverlight In Action"),
        new Book("ASP.NET 3.5 Unleashed"),
        new Book("Introducing Microsoft ASP.NET AJAX")
    };

    Books.ItemsSource = books;
    
}

接下来当用户选择一本书籍时,需要通过Web Client去获取书籍的价格,在Silverlight 2中,所有的网络通信API都设计为了异步模式。在声明一个Web Client实例后,我们需要为它注册DownloadStringCompleted事件处理方法,在下载完成后将会被回调,然后再调用DownloadStringAsync方法开始下载。

void Books_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Uri endpoint = new Uri(String.Format("http://localhost:49955/BookHandler.ashx?No={0}",Books.SelectedIndex));

    WebClient client = new WebClient();
    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
    
    client.DownloadStringAsync(endpoint);
}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        lblPrice.Text = "价格:" + e.Result;
    }
    else
    {
        lblPrice.Text = e.Error.Message;
    }
}

注意大家可以在Web Application Project的属性页中,把ASP.NET Development Server的端口号设置为一个固定的端口号:

TerryLee_Silverlight2_0060

最后完整的代码如下:

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

    void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        List<Book> books = new List<Book>() { 
            new Book("Professional ASP.NET 3.5"),
            new Book("ASP.NET AJAX In Action"),
            new Book("Silverlight In Action"),
            new Book("ASP.NET 3.5 Unleashed"),
            new Book("Introducing Microsoft ASP.NET AJAX")
        };

        Books.ItemsSource = books;
        
    }

    void Books_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Uri endpoint = new Uri(String.Format("http://localhost:49955/BookHandler.ashx?No={0}",Books.SelectedIndex));

        WebClient client = new WebClient();
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
        
        client.DownloadStringAsync(endpoint);
    }

    void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            lblPrice.Text = "价格:" + e.Result;
        }
        else
        {
            lblPrice.Text = e.Error.Message;
        }
    }
}

运行后效果如下:

TerryLee_Silverlight2_0059

当我们选择其中一本书籍时,将会显示出它的价格:

TerryLee_Silverlight2_0061

结束语

本文简单介绍了Silverlight 2中使用Web Client进行通信的知识,在Silverlight 2中,提供的通信API非常丰富,后面将会介绍其他的方式。你可以从这里下载本文示例代码。

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

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

  回复  引用    
#1楼 2008-03-09 16:16 | neo08 [未注册用户]
如何双向通信呢?
  回复  引用  查看    
#2楼 [楼主]2008-03-09 16:18 | TerryLee      
@neo08
在Silverlight 2总对于网络通信这块提供的API非常丰富,如你可以使用WCF或者WebRequest等。。。
  回复  引用    
#3楼 2008-03-09 16:22 | 过客007 [未注册用户]
热切期盼下一篇.
希望楼主放首页原创,这样进入cnblogs就可以直接看到新发布的文章了.
  回复  引用  查看    
#4楼 [楼主]2008-03-09 16:38 | TerryLee      
@过客007
等写完了我会用一篇文章汇总一下,然后再放在首页:)
  回复  引用    
#5楼 2008-03-12 23:42 | learn to use SilverLight [未注册用户]
这里介绍了通过url传参数,
客户端如何将大量的表单数据,比如以xml格式的数据,post到服务器处理?
  回复  引用    
#6楼 2008-03-24 10:29 | 最后一叶 [未注册用户]
。。。李大哥,你写的比偶学的还快。。呼呼。。有点喘8过气了。。不
  回复  引用  查看    
#7楼 [楼主]2008-03-24 21:25 | TerryLee      
@最后一叶
:)
  回复  引用    
#8楼 2008-04-09 17:44 | Meijing [未注册用户]
我在调试楼主的代码时也遇到了和下一篇文章的9楼说的一样的问题。

An exception of type 'System.Security.SecurityException' occurred in System.Windows.dll but was not handled in user code

Additional information: Security error.

问题出现在这一句:
client.DownloadStringAsync(endpoint);

解决方案:
http://silverlight.net/forums/t/10690.aspx
  回复  引用  查看    
#9楼 2008-04-23 19:23 | John Rambo      
李大哥,小弟弟上来冒个泡。顺便问一下貌似sl里的WebRequest不支持自定义HTTP头标和PostData?
  回复  引用    
#10楼 2008-05-16 18:40 | tyzufo [未注册用户]
很厉害,谢谢了!
很有用,谢谢了!
  回复  引用    
#11楼 2008-05-27 11:47 | jazz [未注册用户]
使用IHttpHandler一定要添加System.Web.dll引用,可是我在sliverlight中无法添加这个引用?请教一下是怎么回事?
  回复  引用    
#12楼 2008-06-27 23:00 | veinyf#163.com [未注册用户]
为什么价格显示 安全性错误。也就是e.Error.Messaeg显示错误~!哪里出问题了
  回复  引用  查看    
#13楼 [楼主]2008-06-29 02:32 | TerryLee      
@veinyf#163.com
用的是哪个版本的?
  回复  引用    
#14楼 2008-07-02 21:21 | botsing [未注册用户]
在beta2中void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
方法中e.Error的值始终都是null,那这个该如何判断是否出错
  回复  引用  查看    
#15楼 [楼主]2008-07-02 23:03 | TerryLee      
@botsing
不会吧?报错了e.Error也是为空?

我测试没有出现这个问题啊
  回复  引用    
#16楼 2008-07-03 15:06 | SliverlightDev [未注册用户]
我这里也显示“安全性错误”。用的是Beta2。
  回复  引用    
#17楼 2008-07-04 22:57 | botsing [未注册用户]
@TerryLee
我确实遇到这个问题的,不管什么情况下,调试的时候e.Error值都是null的,不知道哪里出了问题
  回复  引用  查看    
#18楼 [楼主]2008-07-06 22:18 | TerryLee      
@SliverlightDev
显示安全性错误,看看是不是跨域了?
  回复  引用  查看    
#19楼 [楼主]2008-07-06 22:18 | TerryLee      
@botsing
能把代码给我看一下吗?
  回复  引用    
#20楼 2008-07-17 10:37 | wulei99 [未注册用户]
@botsing
我也是,出错以后无论如何e.Error的值都是NULL不能获得出错信息。
使用的是Silverlight 2 Beta 1
  回复  引用  查看    
#21楼 [楼主]2008-07-21 10:29 | TerryLee      
@wulei99
晕倒,赶快升级到Beta 2吧,然后做测试。。。
  回复  引用    
#22楼 2008-07-22 20:22 | MeteorCui [未注册用户]
以后楼主贴代码别忘记引用的namespace
  回复  引用  查看    
#23楼 [楼主]2008-07-22 23:45 | TerryLee      
@MeteorCui
这个貌似没有必要吧,查一下SDK全都有了。。。
  回复  引用  查看    
#24楼 2008-07-28 09:20 | 不若相忘于江湖      
支持楼主。又学到了。
  回复  引用  查看    
#25楼 [楼主]2008-07-28 22:53 | TerryLee      
@不若相忘于江湖
:)
  回复  引用    
#26楼 2008-08-05 09:25 | 吕不韦 [未注册用户]
谢谢了,终于搞出来了,好像这个东西和web应用程序里面的东西不太一样,连控件都变得不一样了,差别好大,搞了半天,试了好几个方法
  回复  引用    
#27楼 2008-08-05 16:18 | liveabc [未注册用户]
李大哥,我这无法使用Ihttphandler接口呀。也不不能引用system.web.如何解决?
  回复  引用  查看    
#28楼 [楼主]2008-08-06 13:21 | TerryLee      
@吕不韦
肯定不一样了
  回复  引用  查看    
#29楼 [楼主]2008-08-06 13:21 | TerryLee      
@liveabc
Ihttphandler应该在Web测试项目中,而不是在Silverlight项目中。
  回复  引用    
#30楼 2008-08-07 23:48 | 排骨面_1234 [未注册用户]
--引用--------------------------------------------------
TerryLee: @liveabc
Ihttphandler应该在Web测试项目中,而不是在Silverlight项目中。
--------------------------------------------------------
请问,如果是这样的话,那么SilverLight项目不是要引用Web测试项目了?
因为:

void UserControl_Loaded(object sender, RoutedEventArgs e)
{
List<Book> books = new List<Book>() {
new Book("Professional ASP.NET 3.5"),
new Book("ASP.NET AJAX In Action"),
new Book("Silverlight In Action"),
new Book("ASP.NET 3.5 Unleashed"),
new Book("Introducing Microsoft ASP.NET AJAX")
};

Books.ItemsSource = books;

}
这里怎么引用得到Book ?

  回复  引用  查看    
#31楼 2008-08-11 12:55 | 孤傲猎手      
为什么提示 在System.Net下找不到DownloadStringCompletedEventArgs呢?新版的silverlight修改位置了吗?
  回复  引用  查看    
#32楼 [楼主]2008-08-13 21:42 | TerryLee      
@排骨面_1234
Book类是定义在Silverlight中的啊,不涉及到什么引用的问题。
  回复  引用  查看    
#33楼 [楼主]2008-08-13 21:46 | TerryLee      
@孤傲猎手
可能是,查一下SDK吧
  回复  引用  查看    
#34楼 2008-08-15 16:58 | 排骨面      
@TerryLee
哦~~~~ 搜得斯勒~~~
谢谢大大~~
--引用--------------------------------------------------
TerryLee: @排骨面_1234
Book类是定义在Silverlight中的啊,不涉及到什么引用的问题。
--------------------------------------------------------

  回复  引用  查看    
#35楼 [楼主]2008-08-20 10:33 | TerryLee      
@排骨面
:)
  回复  引用  查看    
#36楼 2008-08-20 22:35 | LevinLee      
SilverLight程序集里没有找到System.Web,博主这是为什么呢
  回复  引用  查看    
#37楼 [楼主]2008-08-20 23:36 | TerryLee      
@LevinLee
呵呵,我一再强调,Silverlight是一种客户端技术,它虽然支持.NET Framework,但仅仅是.NET Framework很小的一个子集。不是说任何程序集都可以添加的。
  回复  引用    
#38楼 2008-08-25 10:27 | zhuzi [未注册用户]
请问,如果是这样的话,那么SilverLight项目不是要引用Web测试项目了?
因为:

void UserControl_Loaded(object sender, RoutedEventArgs e)
{
List<Book> books = new List<Book>() {
new Book("Professional ASP.NET 3.5"),
new Book("ASP.NET AJAX In Action"),
new Book("Silverlight In Action"),
new Book("ASP.NET 3.5 Unleashed"),
new Book("Introducing Microsoft ASP.NET AJAX")
};

Books.ItemsSource = books;

}
这里怎么引用得到Book ?


我也有同样地问题 ,提示The type or namespace name 'Book' could not be found (are you missing a using directive or an assembly reference?)


  回复  引用  查看    
#39楼 [楼主]2008-08-25 11:25 | TerryLee      
@zhuzi
你应该在Silverlight项目中同样有一个Book类才对。。
  回复  引用    
#40楼 2008-08-25 17:18 | ChMal [未注册用户]
BookHandler 是在web测试项目右键->添加->新建项->一般处理程序

  回复  引用  查看    
#41楼 [楼主]2008-08-26 09:52 | TerryLee      
@ChMal
这个是哪个问题?有点晕。。。
  回复  引用    
#42楼 2008-08-28 10:57 | littlespiderman [未注册用户]
关于8楼说的问题,我也遇到了

如果,运行F5,程序本身没有问题。但是使用那个Html测试页,就

出现Security Error.不知道楼主有解决方法没有。
  回复  引用    
#43楼 2008-08-28 11:04 | littlespiderman [未注册用户]
还有个问题,我在使用这个例子的时候,用鼠标滑轮来上下滑动,Book选项列表

但是,没有反应,只能托动scrollBar。不知道如何解决这个问题?
  回复  引用  查看    
#44楼 2008-09-08 17:50 | pdfw      
--引用--------------------------------------------------
孤傲猎手: 为什么提示 在System.Net下找不到DownloadStringCompletedEventArgs呢?新版的silverlight修改位置了吗?
--------------------------------------------------------
没有修改位置,不过你大概没有添加system.net的引用,这个引用不是默认添加的,需要自己添加。
  回复  引用  查看    
#45楼 [楼主]2008-09-10 23:48 | TerryLee      
@pdfw
是这样的:)
  回复  引用  查看    
#46楼 2008-10-21 11:34 | 火蛇儿.net      
开始从wpf转向silverlight了,头痛得是一直干得是winform, web的基础太薄弱。

Terry: 可以给些学习建议吗?我想通过silverlight的学习去带动web的学习
  回复  引用  查看    
#47楼 [楼主]2008-10-24 10:20 | TerryLee      
@火蛇儿.net
如果有WPF的基础,学习Silverlight应该是一件很容易的事,呵呵,现在Silverlight2正式版的资料很少,只能通过查看SDK了。
  回复  引用    
#48楼 2008-11-06 23:51 | 冻结 [未注册用户]
出现“安全性错误”的,也就是e.Error!=null的,
不要运行sl项目和web项目里生成的那个静态测试页,要在vs解决方案管理器里右键web项目那个测试页,选择在浏览器里打开,这样就就可以了,

貌似url地址必须是网络地址(即http://....)才可以正常使用WebClient
  回复  引用  查看    
#49楼 [楼主]2008-11-07 00:01 | TerryLee      
--引用--------------------------------------------------
冻结: 出现“安全性错误”的,也就是e.Error!=null的,
不要运行sl项目和web项目里生成的那个静态测试页,要在vs解决方案管理器里右键web项目那个测试页,选择在浏览器里打开,这样就就可以了,

貌似url地址必须是网络地址(即http://....)才可以正常使用WebClient
--------------------------------------------------------
没看懂,你说的是什么问题?
  回复  引用  查看    
#50楼 2008-11-16 17:06 | Jasondong      
请教楼主,运行的时候不执行UserControl_Loaded这个方法是什么原因?
  回复  引用  查看    
#51楼 [楼主]2008-11-17 23:19 | TerryLee      
@Jasondong
看你有没有在Xaml中注册事件?
  回复  引用  查看    
#52楼 2008-11-19 18:19 | Jasondong      
@TerryLee
是没有注册,没有认真看,还以为这个事件跟PageLoad一样不需要注册 呵呵
谢谢李大哥!
  回复  引用  查看    
#53楼 [楼主]2008-11-19 23:38 | TerryLee      
@Jasondong
:)
  回复  引用    
#54楼 2008-12-05 11:40 | 小虾米 [未注册用户]
楼主真是热心人呢,辛苦咯!

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-09 17:19 编辑过
Google站内搜索



相关文章:


相关搜索:
Silverlight

相关链接:

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