Silverlight中我们很多时候需要上传下载数据的时候,在本节将讲述使用WebClient上传String、下载String、上传Stream流、下载Stream流的4个方法和相应的事件。下面我们首先认识一下WebClient类。
WebClient的主要函数如下:
•OpenReadAsync 打开流向指定资源的可读流。
•OpenWriteAsync 打开一个流以将数据写入指定的资源。这些方法不会阻止调用线程。
•DownloadStringAsync 以字符串形式下载位于指定 Uri 的资源。
•UploadStringAsync 将指定的字符串上载到指定的资源。这些方法不会阻止调用线程。
WebClient的主要事件如下:
•OpenReadCompleted 在异步资源读取操作完成时发生。
•OpenWriteCompleted 在打开流以将数据写入资源的异步操作完成时发生。
•DownloadStringCompleted 在异步资源下载操作完成时发生。
•DownloadProgressChanged 在异步下载操作成功传输部分或全部数据后发生。
•UploadStringCompleted 在异步字符串上载操作完成时发生。
•UploadProgressChanged 在异步上载操作成功转换部分或全部数据后发生。
上面的函数和事件在Silverlight的API中有详细的解释,在本文中不再复述。下面我们来看看一个实例来使用WebClient上传String、下载String、上传Stream流、下载Stream流。
首先我们准备XAML文件的前台代码,其内有四个按钮,分别代表上传String、下载String、上传Stream流、下载Stream流的按钮。代码如下:
<Canvas Name="lRoot"></Canvas>
<Button Content="WebClient下载XAP" Height="23" HorizontalAlignment="Left" Margin="410,60,0,0" Name="button1" VerticalAlignment="Top" Width="178" Click="buttonOpenReadAsync_Click"/>
<Button Content="DownloadStringAsync下载XML" Height="23" HorizontalAlignment="Left" Margin="410,100,0,0" Name="button2" VerticalAlignment="Top" Width="178" Click="buttonDownloadStringAsync_Click"/>
<Button Content="UploadStringAsync上传String" Height="23" HorizontalAlignment="Left" Margin="410,140,0,0" Name="button3" VerticalAlignment="Top" Width="178" Click="buttonUploadStringAsync_Click"/>
<Button Content="OpenWriteAsync上传图片" Height="23" HorizontalAlignment="Left" Margin="410,180,0,0" Name="button4" VerticalAlignment="Top" Width="178" Click="buttonOpenWriteAsync_Click"/>
</Grid>
•上传String操作如下:
首先建立一个TestHandle.ashx,向这个文件内部写入以下代码以接收Silverlight中上传的String字符。
/// TestHandle 的摘要说明
///</summary>
publicclass TestHandle : IHttpHandler
{
publicvoid ProcessRequest(HttpContext context)
{
int bytelength = context.Request.ContentLength;
byte[] inputbytes = context.Request.BinaryRead(bytelength);
string message = System.Text.Encoding.Default.GetString(inputbytes);
context.Response.ContentType ="text/plain";
context.Response.Write("你已经提交数据:"+ message);
}
publicbool IsReusable
{
get
{
returnfalse;
}
}
}
我们再看Silverlight端代码如下:
privatevoid buttonUploadStringAsync_Click(object sender, RoutedEventArgs e)
{
//开始调用UploadStringAsync异步上传String
Appclient.UploadStringAsync(new Uri("http://localhost:3993/TestHandle.ashx", UriKind.RelativeOrAbsolute), "<TD></TD>");
Appclient.UploadStringCompleted +=new UploadStringCompletedEventHandler(Appclient_UploadStringCompleted);
}
void Appclient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
MessageBox.Show(e.Result);
Appclient.UploadStringCompleted -=new UploadStringCompletedEventHandler(Appclient_UploadStringCompleted);
}
#endregion
•下载String操作如下:
下载ClientBin目录下已经存在的XML文件
privatevoid buttonDownloadStringAsync_Click(object sender, RoutedEventArgs e)
{
//开始调用DownloadStringAsync异步下载文档并且读取它
Appclient.DownloadStringAsync(new Uri("http://localhost:3993/ClientBin/222.xml", UriKind.RelativeOrAbsolute));
Appclient.DownloadStringCompleted +=new DownloadStringCompletedEventHandler(Appclient_DownloadStringCompleted);
}
void Appclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
MessageBox.Show(e.Result);
Appclient.DownloadStringCompleted -=new DownloadStringCompletedEventHandler(Appclient_DownloadStringCompleted);
}
#endregion
•上传Stream操作如下:
建立一个AddFileHandle.ashx,向这个文件内部写入以下代码以接收Silverlight中上传的Stream数据流。
/// AddFileHandle 的摘要说明
///</summary>
publicclass AddFileHandle : IHttpHandler
{
publicvoid ProcessRequest(HttpContext context)
{
//获取上传的数据流
using (Stream sr = context.Request.InputStream)
{
string filename ="Fir";
byte[] buffer =newbyte[4096];
int bytesRead =0;
//将当前数据流写入ClientBin文件下Fir.jpg文件中
using (FileStream fs = File.Create(context.Server.MapPath("ClientBin/"+ filename +".jpg"), 4096))
{
while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) >0)
{
//将数据写入文件
fs.Write(buffer, 0, bytesRead);
}
}
}
}
publicbool IsReusable
{
get
{
returnfalse;
}
}
}
Silverlight读取图片数据,然后传到服务器端(注:此处没有验证传什么数据,如有需要自己调用OpenFileDialog.Filter即可),代码如下:
privatevoid buttonOpenWriteAsync_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialog =new OpenFileDialog();
if (dialog.ShowDialog() ==true)
{
//开始调用OpenWriteAsync方法上传数据
Appclient.OpenWriteAsync(new Uri("http://localhost:3993/AddFileHandle.ashx", UriKind.RelativeOrAbsolute), "POST", dialog.File.OpenRead());
Appclient.OpenWriteCompleted +=new OpenWriteCompletedEventHandler(Appclient_OpenWriteCompleted);
}
}
void Appclient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
//将图片数据流发送到服务器上
Stream inputStream = e.UserState as Stream;
Stream outputStream = e.Result;
byte[] buffer =newbyte[4096];
int bytesRead =0;
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) >0)
{
outputStream.Write(buffer, 0, bytesRead);
}
outputStream.Close();
inputStream.Close();
MessageBox.Show("图片上传成功!");
Appclient.OpenWriteCompleted -=new OpenWriteCompletedEventHandler(Appclient_OpenWriteCompleted);
}
#endregion
•下载Stream操作如下:
本例采用上一节的源码,下载Stream流,然后反射为对象,源码如下:
privatevoid buttonOpenReadAsync_Click(object sender, RoutedEventArgs e)
{
//1 •使用WebClient下载SLRandarHitTest.xap文件,进行异步读取。
Appclient.OpenReadAsync(new Uri("SLRandarHitTest.xap", UriKind.Relative));
Appclient.OpenReadCompleted +=new OpenReadCompletedEventHandler(Appclient_OpenReadCompleted);
}
void Appclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
CreateXAPResource("SLRandar.dll", "SLRandar.MainPage", e.Result);
Appclient.OpenReadCompleted -=new OpenReadCompletedEventHandler(Appclient_OpenReadCompleted);
}
///<summary>
/// 创建XAP包的反射实例并且加装到Canvas中
///</summary>
///<param name="dllStr">XAP包中的编译完成的运行代码的DLL文件</param>
///<param name="mainStr">需要实例化的启动页面</param>
///<param name="resultStream">使用WebClient下载到的数据流</param>
privatevoid CreateXAPResource(string dllStr, string mainStr, Stream resultStream)
{
//3 •获取其他包提供的资源流信息
StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new StreamResourceInfo(resultStream as Stream, null), new Uri(dllStr, UriKind.RelativeOrAbsolute));
//4 •对Stream进行反射
AssemblyPart assemblyPart =new AssemblyPart();
Assembly assembly = assemblyPart.Load(streamResourceInfo.Stream);
//5 •(创建实例
var uc = (UserControl)assembly.CreateInstance(mainStr);
lRoot.Children.Clear();
lRoot.Children.Add(uc);
}
#endregion