SilverLight学习笔记--使用WebClient实现通讯(一)(上传和下载字符串数据)

    我们曾经学习过如何在Silverlight中用HttpWebRequest通讯。这里我们学习如何使用WebClient实现通讯。

一、什么是WebClient类
   1、基本知识
    WebClient类是Mircsoft在.NET框架下提供的向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。通过这个类,大家可以在脱离浏览器的基础上模拟浏览器对互联网上的资源的访问和发送信息。它使人们使用起来更加简单方便,然而它也有先天不足的地方。那就是缺少对cookies/session的支持。
    WebClient类为Silverlight插件提供了一整套的HTTP客户端功能,可以下载应用程序数据,比如XAML内容,附加的程序集或者视频图片等媒体文件。WebClient可以根据程序须要即时下载内容,可以异步呈现和使用下载的内容,而不是随HTML页面一起下载。
    WebClient类提供了发起请求、监视请求的进度以及检索下载内容、上传数据到指定资源等功能。在Silverlight 2中,只能使用WebClient发起异步的请求,如开发一个视频播放应用程序,在应用程序加载时,选择开始请求每一部影片,使其加载到浏览器缓存中,这样可以避免缓冲延迟。
   由于WebClient请求都是异步的,使用的是基于异步事件编程模型,大部分交互操作都是依靠事件处理来完成的,通常须要定义如下一个或者多个事件处理函数。

   2、相关方法
将数据上载到资源的 WebClient 方法

OpenWriteAsync: 检索 Stream,它在不阻止调用线程的情况下以异步方式将数据发送到资源。
UploadStringAsync: 在不阻止调用线程的情况下,将 String 发送到资源。

从资源下载数据的 WebClient 方法

DownloadStringAsync: 在不阻止调用线程的情况下,从资源下载 String。
OpenReadAsync : 在不阻止调用线程的情况下,以异步方式从资源返回数据。


您可以使用 CancelAsync 方法取消尚未完成的异步操作。

 3、两种工作方式:
   A、以字符串形式下载和上传数据
  使用WebClient可以以字符串形式下载数据,当请求一个指定地址的字符串时,调用DownloadStringAsync方法,操作完成后将触发DownloadStringCompleted事件,在该事件处理方法中能够接收到一个类型为DownloadStringCompletedEventArgs的参数,它的Result属性的类型为String,我们可以通过该属性来获得最终的字符串结果,它可以是一段普通的文本或一段XML文本等。

   B、 以流形式下载和上传数据
  使用WebClient同样可以以流形式下载数据,当请求下载的资源是一个流时,可调用OpenReadAsync方法,此操作完成后将触发OpenReadCompleted事件,在该事件处理方法中能够接收到一个类型为OpenReadCompletedEventArgs的参数,它的Result属性类型为Stream,使用此属性能够获取到最终的流结果。

 二、示例如何实现通讯 (以字符串形式下载和上传数据)

   新建Silverlight应用程序SLWebClient。如下图:

                        
编写界面布局,XAML如下:

< UserControl x:Class = " SLWebClient.Page "
    xmlns
= " http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
    xmlns:x
= " http://schemas.microsoft.com/winfx/2006/xaml "  
    Width
= " 400 "  Height = " 400 " >
    
< StackPanel Height = " 400 "  Width = " 400 "  Orientation = " Vertical " >
        
< StackPanel Height = " 250 "  Width = " 400 "  Background = " Bisque " >
            
< TextBlock Text = " 以字符串形式下载数据 "  TextAlignment = " Center "  FontSize = " 16 "  Foreground = " Red " ></ TextBlock >
            
< Button x:Name = " btnLoadCity "  Content = " 加裁城市信息 "  Width = " 200 "  Click = " btnLoadCity_Click " ></ Button >
            
< Button x:Name = " btnLoadWeather "  Content = " 加裁天气信息 "  Width = " 200 "  Click = " btnLoadWeather_Click " ></ Button >
            
< TextBlock Text = " 信息加载如下.. "   TextAlignment = " Center "  Foreground = " Green " >   </ TextBlock >
              
            
< ListBox x:Name = " lstBxResult "  Height = " 120 "  Width = " 350 " >
                
            
</ ListBox >
            
< TextBlock x:Name = " tbResult "  Text = " 当前无内容 "  TextAlignment = " Center "    TextWrapping = " Wrap "   Width = " 300 "  Height = " 30 "  Foreground = " Blue " ></ TextBlock >
        
</ StackPanel >
        
< StackPanel Width = " 400 "  Height = " 100 "  Background = " Lavender " >
            
< TextBlock Text = " 以字符串形式上传数据 "  TextAlignment = " Center "  FontSize = " 16 "  Foreground = " Red " ></ TextBlock >
            
< TextBox x:Name = " txtBxUploadStr "  Width = " 350 "  Height = " 40 "  Text = " This is the Text Content come from Silverlight TextBox. "  TextWrapping = " Wrap " ></ TextBox >
             
< Button x:Name = " btnUploadText "  Width = " 200 "  Height = " 25 "  Content = " 上传文本信息 "  Margin = " 6 "  Click = " btnUploadText_Click " ></ Button >
        
</ StackPanel >
    
</ StackPanel >
</ UserControl >


                                                       界面如下图:
                        

          在客户端,我们要完成两段代码:

    i、向服务器端发出"下载字符串"请求,相关代码如下:

         #region   以字符串形式下载信息
        
private   void  btnLoadCity_Click( object  sender, RoutedEventArgs e)
        {
            GetInfomation(
" city " );
        }

        
private   void  btnLoadWeather_Click( object  sender, RoutedEventArgs e)
        {
            GetInfomation(
" weather " );
        }

        
private   void  GetInfomation( string  infoType)
        {
           
//  string tranType = "Json";
             string  tranType  =   " TextStr " ;
            Uri endpoint 
=   new  Uri(String.Format( " http://localhost:49417/WebClientDownHandler.ashx?infoType={0}&tranType={1} " , infoType, tranType));
            WebClient client 
=   new  WebClient();
            client.DownloadStringCompleted 
+=   new  DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(endpoint);
        }


        
void  client_DownloadStringCompleted( object  sender, DownloadStringCompletedEventArgs e)
        {
            
string  RetStr  =   "" ;
            
if  (e.Error  ==   null )
            {
                
// RetStr = "WebClient成功通讯";
                RetStr  =  e.Result;
                ShowGetRetList(RetStr);
                
            }
            
else
            {
                RetStr 
=  e.Error.Message;
            }
            
this .tbResult.Text  =  RetStr;   // 显示操作结果信息

        }


        
// 把传递过来的字符串分解为字符串数组并显示在List控件中
         private   void  ShowGetRetList( string  retStr)
        {
            
char  splitChar  =   ' : ' // 定义字符串分隔符
             this .lstBxResult.Items.Clear();  // 先清空ListBox中的显示
             string [] retStrArray  =  retStr.Split(splitChar);
            
for  ( int  i  =   0 ; i  <  retStrArray.Length; i ++ )
            {
                
this .lstBxResult.Items.Add(retStrArray[i]);
            }

        }
        
#endregion


   ii、向服务器端发出"上传字符串"请求,相关代码如下:

         #region    以字符串形式上传信息

        
private   void  btnUploadText_Click( object  sender, RoutedEventArgs e)
        {
            
//  要上传的文本数据
             string  data  =   this .txtBxUploadStr.Text.ToString();

            Uri endpoint 
=   new  Uri( " http://localhost:49417/WebClientUpLoadHandler.ashx " );

            WebClient client 
=   new  WebClient();
            client.UploadStringCompleted 
+=
            
new  UploadStringCompletedEventHandler(client_UploadStringCompleted);
            client.UploadStringAsync(endpoint, 
" POST " , data);
        }

        
void  client_UploadStringCompleted( object  sender,UploadStringCompletedEventArgs e)
        {
           MessageBox.Show(e.Result);
        }
        
#endregion


Page.xaml.cs全部代码如下:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;

using  System.IO;
using  System.Text;
using  System.Runtime.Serialization.Json;


namespace  SLWebClient
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class Page : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
public Page()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InitializeComponent();
        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
以字符串形式下载信息#region  以字符串形式下载信息
        
private void btnLoadCity_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            GetInfomation(
"city");
        }


        
private void btnLoadWeather_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            GetInfomation(
"weather");
        }


        
private void GetInfomation(string infoType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
           
// string tranType = "Json";
            string tranType = "TextStr";
            Uri endpoint 
= new Uri(String.Format("http://localhost:49417/WebClientDownHandler.ashx?infoType={0}&tranType={1}", infoType, tranType));
            WebClient client 
= new WebClient();
            client.DownloadStringCompleted 
+= new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(endpoint);
        }



        
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
string RetStr = "";
            
if (e.Error == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
//RetStr = "WebClient成功通讯";
                RetStr = e.Result;
                ShowGetRetList(RetStr);
                
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                RetStr 
= e.Error.Message;
            }

            
this.tbResult.Text = RetStr;  //显示操作结果信息

        }



        
//把传递过来的字符串分解为字符串数组并显示在List控件中
        private void ShowGetRetList(string retStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
char splitChar = ':'//定义字符串分隔符
            this.lstBxResult.Items.Clear(); //先清空ListBox中的显示
            string[] retStrArray = retStr.Split(splitChar);
            
for (int i = 0; i < retStrArray.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
this.lstBxResult.Items.Add(retStrArray[i]);
            }


        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
以字符串形式上传信息#region   以字符串形式上传信息

        
private void btnUploadText_Click(object sender, RoutedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 要上传的文本数据
            string data = this.txtBxUploadStr.Text.ToString();

            Uri endpoint 
= new Uri("http://localhost:49417/WebClientUpLoadHandler.ashx");

            WebClient client 
= new WebClient();
            client.UploadStringCompleted 
+=
            
new UploadStringCompletedEventHandler(client_UploadStringCompleted);
            client.UploadStringAsync(endpoint, 
"POST", data);
        }


        
void client_UploadStringCompleted(object sender,UploadStringCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
           MessageBox.Show(e.Result);
        }

        
#endregion


    }

}



   在服务器端,我们要建立两个Handler

  WebClientDownHandler.ashx :处理客户端的下载请求.
  WebClientUpLoadHandler.ashx :处理客户端的上传请求

 WebClientDownHandler.ashx --负责处理下载字符串请求的Handler代码如下:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;

using  System.Text;
using  System.IO;

namespace  SLWebClient.Web
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class WebClientHandler : IHttpHandler
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
CityLis字符串数组#region CityLis字符串数组
        
public static readonly string[] CityList = new string[]
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
                
"BeiJing",
                
"ChengDu",
                
"XiangGang",
                
"ChongQing",
                
"ShenZheng"
        }
;
        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
WeatherList字符串数组#region WeatherList字符串数组
        
public static readonly string[] WeatherList = new string[]
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
                
"晴天",
                
"阴天",
                
"多云",
                
"小雨"
        }
;
        
#endregion



ContractedSubBlock.gifExpandedSubBlockStart.gif        
处理客户端请求并返回处理结果#region  处理客户端请求并返回处理结果
        
public void ProcessRequest(HttpContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//读取从客户端传递过来的参数
            string infoTypeStr = context.Request.QueryString["infoType"].ToString();
            
string tranTypeStr = context.Request.QueryString["tranType"].ToString();

            
string retValueStr = "";

            
if (tranTypeStr == "TextStr")
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
//根据客户端传参判断应该从服务器端返回什么结果信息
                switch (infoTypeStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
case "city": retValueStr = combineStringArry(CityList); break;   //返回city字符串数组
                    case "weather": retValueStr = combineStringArry(WeatherList); break;  //返回weather字符串数组

                }


            }


            context.Response.ContentType 
= "text/plain";
            context.Response.Write(retValueStr);
        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
把字符串拼接成字符串数组并返回#region 把字符串拼接成字符串数组并返回
        
public string combineStringArry(string[] strArray)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
//把字符串拼接成字符串数组并返回
            string t = "";
            
char splitChar = ':'//定义字符串数组中的分隔符

            
for (int i = 0; i < strArray.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (i == strArray.Length - 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    t 
= t + strArray[i].ToString();
                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    t 
= t + strArray[i].ToString() + splitChar;
                }


            }

            
return t;

        }

        
#endregion


        
public bool IsReusable
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return false;
            }

        }

    }

}



WebClientUpLoadHandler.ashx--负责处理上传字符串请求的Handler代码如下:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;

using  System.Text;
using  System.IO;

namespace  SLWebClient.Web
ExpandedBlockStart.gifContractedBlock.gif
{

    
public class WebClientUpLoadHandler : IHttpHandler
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{

        
public void ProcessRequest(HttpContext context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//获取从Silverlight客户端传来的信息
            int length = context.Request.ContentLength; 
            
byte[] bytes = context.Request.BinaryRead(length);

            
string txtContent = Encoding.Default.GetString(bytes); 

            
//从服务器端返回信息
            context.Response.ContentType = "text/plain";
            context.Response.Write(
"服务器端成功收到信息,文本内容是: " + txtContent);
        }


        
public bool IsReusable
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return false;
            }

        }

    }

}


生成应用程序并运行,运行效果如下:



前往:Silverlight学习笔记清单
本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值