好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Silverlight文件上传下载实现方法(下载保存)

search了非常多的文章,总算勉强实现了。有许多不完善的地方。


在HCLoad.Web项目下新建目录Pics复制一张图片到根目录下。

图片名:Bubble.jpg 右击->属性->生成操作:Resource


UC_UpDown.xaml

?

< UserControl x:Class = "HCLoad.UC_UpDown"

   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"

   Width = "500" Height = "500" >

   < StackPanel Background = "White" Height = "450" >

     < Button Content = "down" Click = "Button_Click" ></ Button >

     < HyperlinkButton Content = "下载保存" NavigateUri = "http://localhost:4528/download.ashx?fileName=aa.txt" TargetName = "_self" x:Name = "lBtnDown" />

     < TextBlock x:Name = "tbMsgString" Text = "下载进度" TextAlignment = "Center" Foreground = "Green" ></ TextBlock >

     < Button x:Name = "btnDownload" Content = "DownLoad Pictures" Width = "150" Height = "35" Margin = "15" Click = "btnDownload_Click" />

     < Border Background = "Wheat" BorderThickness = "5" Width = "400" Height = "280" >

       < Image x:Name = "imgDownLoad" Width = "400" Height = "300" Margin = "15" Stretch = "Fill" />

     </ Border >

     < Button x:Name = "btnUpLoad" Content = "UpLoad Pictures" Width = "150" Height = "35" Margin = "15" Click = "btnUpLoad_Click" />

   </ StackPanel >

</ UserControl >

UC_UpDown.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.Windows.Media.Imaging; //因为要使用BitmapImage

using System.IO; //因为要使用Stream

 

namespace HCLoad

{

   public partial class UC_UpDown : UserControl

   {

     //1、WebClient 对象一次只能启动一个请求。如果在一个请求完成(包括出错和取消)前,即IsBusy为true时,进行第二个请求,则第二个请求将会抛出 NotSupportedException 类型的异常

     //2、如果 WebClient 对象的 BaseAddress 属性不为空,则 BaseAddress 与 URI(相对地址) 组合在一起构成绝对 URI

     //3、WebClient 类的 AllowReadStreamBuffering 属性:是否对从 Internet 资源接收的数据做缓冲处理。默认值为true,将数据缓存在客户端内存中,以便随时被应用程序读取

 

 

 

     //获取选定图片信息

     System.IO.FileInfo fileinfo;

     public UC_UpDown()

     {

       InitializeComponent();

     }

     #region 下载图片

     private void btnDownload_Click( object sender, RoutedEventArgs e)

     {

       //向指定的Url发送下载流数据请求

       String imgUrl = "http://localhost:4528/Bubble.jpg" ;

       Uri endpoint = new Uri(imgUrl);

 

       WebClient client = new WebClient();

       client.OpenReadCompleted += new OpenReadCompletedEventHandler(OnOpenReadCompleted);

       client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(clientDownloadStream_DownloadProgressChanged);

       client.OpenReadAsync(endpoint);

     }

     void OnOpenReadCompleted( object sender, OpenReadCompletedEventArgs e)

     {

 

       //OpenReadCompletedEventArgs.Error - 该异步操作期间是否发生了错误

       //OpenReadCompletedEventArgs.Cancelled - 该异步操作是否已被取消

       //OpenReadCompletedEventArgs.Result - 下载后的 Stream 类型的数据

       //OpenReadCompletedEventArgs.UserState - 用户标识

 

       if (e.Error != null )

       {

         MessageBox.Show(e.Error.ToString());

         return ;

       }

       if (e.Cancelled != true )

       {

         //获取下载的流数据(在此处是图片数据)并显示在图片控件中

         //Stream stream = e.Result;

         //BitmapImage bitmap = new BitmapImage();

         //bitmap.SetSource(stream);

         //imgDownLoad.Source = bitmap;

         Stream clientStream = e.UserState as Stream;

         Stream serverStream = (Stream)e.Result;

         byte [] buffer = new byte [serverStream.Length];

         serverStream.Read(buffer, 0, buffer.Length);

         clientStream.Write(buffer, 0, buffer.Length);

         clientStream.Close();

         serverStream.Close();

 

       }

 

 

 

     }

 

     void clientDownloadStream_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e)

     {

       //DownloadProgressChangedEventArgs.ProgressPercentage - 下载完成的百分比

       //DownloadProgressChangedEventArgs.BytesReceived - 当前收到的字节数

       //DownloadProgressChangedEventArgs.TotalBytesToReceive - 总共需要下载的字节数

       //DownloadProgressChangedEventArgs.UserState - 用户标识

 

       this .tbMsgString.Text = string .Format( "完成百分比:{0} 当前收到的字节数:{1} 资料大小:{2} " ,

        e.ProgressPercentage.ToString() + "%" ,

        e.BytesReceived.ToString(),

        e.TotalBytesToReceive.ToString());

 

     }

 

     #endregion

 

     #region 上传图片

     private void btnUpLoad_Click( object sender, RoutedEventArgs e)

     {

       /**/

       /*

      *   OpenWriteCompleted - 在打开用于上传的流完成时(包括取消操作及有错误发生时)所触发的事件

      *   WriteStreamClosed - 在写入数据流的异步操作完成时(包括取消操作及有错误发生时)所触发的事件

      *   UploadProgressChanged - 上传数据过程中所触发的事件。如果调用 OpenWriteAsync() 则不会触发此事件

      *   Headers - 与请求相关的的标头的 key/value 对**

      *   OpenWriteAsync(Uri address, string method, Object userToken) - 打开流以使用指定的方法向指定的 URI 写入数据

      *     Uri address - 接收上传数据的 URI

      *     string method - 所使用的 HTTP 方法(POST 或 GET)

      *     Object userToken - 需要上传的数据流

      */

 

 

       OpenFileDialog openFileDialog = new OpenFileDialog()

       { //弹出打开文件对话框要求用户自己选择在本地端打开的图片文件

         Filter = "Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*" ,

         Multiselect = false //不允许多选

       };

 

       if (openFileDialog.ShowDialog() == true ) //.DialogResult.OK)

       {

         //fileinfo = openFileDialog.Files; //取得所选择的文件,其中Name为文件名字段,作为绑定字段显示在前端

         fileinfo = openFileDialog.File;

 

         if (fileinfo != null )

         {

           WebClient webclient = new WebClient();

 

           string uploadFileName = fileinfo.Name.ToString(); //获取所选文件的名字

 

           #region 把图片上传到服务器上

 

           Uri upTargetUri = new Uri(String.Format( "http://localhost:4528/WebClientUpLoadStreamHandler.ashx?fileName={0}" , uploadFileName), UriKind.Absolute); //指定上传地址

 

           webclient.OpenWriteCompleted += new OpenWriteCompletedEventHandler(webclient_OpenWriteCompleted);

           webclient.Headers[ "Content-Type" ] = "multipart/form-data" ;

 

           webclient.OpenWriteAsync(upTargetUri, "POST" , fileinfo.OpenRead());

           webclient.WriteStreamClosed += new WriteStreamClosedEventHandler(webclient_WriteStreamClosed);

 

           #endregion

 

         }

         else

         {

           MessageBox.Show( "请选取想要上载的图片!!!" );

         }

       }

 

     }

 

 

 

     void webclient_OpenWriteCompleted( object sender, OpenWriteCompletedEventArgs e)

     {

 

       //将图片数据流发送到服务器上

 

       // e.UserState - 需要上传的流(客户端流)

       Stream clientStream = e.UserState as Stream;

       // e.Result - 目标地址的流(服务端流)

       Stream serverStream = e.Result;

       byte [] buffer = new byte [4096];

       int readcount = 0;

       // clientStream.Read - 将需要上传的流读取到指定的字节数组中

       while ((readcount = clientStream.Read(buffer, 0, buffer.Length)) > 0)

       {

         // serverStream.Write - 将指定的字节数组写入到目标地址的流

         serverStream.Write(buffer, 0, readcount);

       }

       serverStream.Close();

       clientStream.Close();

 

 

     }

 

     void webclient_WriteStreamClosed( object sender, WriteStreamClosedEventArgs e)

     {

       //判断写入是否有异常

       if (e.Error != null )

       {

         System.Windows.Browser.HtmlPage.Window.Alert(e.Error.Message.ToString());

       }

       else

       {

         System.Windows.Browser.HtmlPage.Window.Alert( "图片上传成功!!!" );

       }

     }

     #endregion

 

     private void Button_Click( object sender, RoutedEventArgs e)

     {

       //这种方法搞不定,好像提示跨域操作。

       //提示:错误:Unhandled Error in Silverlight Application 跨线程访问无效。

       //Uri upTargetUri = new Uri(String.Format("http://localhost:4528/download.ashx?filename={0}", "123.jpg"), UriKind.Absolute); //指定上传地址

       //WebRequest request = WebRequest.Create(upTargetUri);

       //request.Method = "GET";

       //request.ContentType = "application/octet-stream";

       //request.BeginGetResponse(new AsyncCallback(RequestReady), request);

 

       //通过调用js代码下载,比较简单。

       System.Windows.Browser.HtmlPage.Window.Eval( "window.location.href='http://localhost:4528/download.ashx?filename=123.jpg';" );

     }

     void RequestReady(IAsyncResult asyncResult)

     {

       MessageBox.Show( "RequestComplete" );

     }

 

   }

}

在HCLoad.Web项目下新建WebClientUpLoadStreamHandler.ashx

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

using System.IO; //因为要用到Stream

 

namespace HCLoad.Web

{

   public class WebClientUpLoadStreamHandler : IHttpHandler

   {

 

     public void ProcessRequest(HttpContext context)

     {

       //获取上传的数据流

       string fileNameStr = context.Request.QueryString[ "fileName" ];

       Stream sr = context.Request.InputStream;

       try

       {

         string filename = "" ;

 

         filename = fileNameStr;

 

         byte [] buffer = new byte [4096];

         int bytesRead = 0;

         //将当前数据流写入服务器端文件夹ClientBin下

         string targetPath = context.Server.MapPath( "Pics/" + filename + ".jpg" );

         using (FileStream fs = File.Create(targetPath, 4096))

         {

           while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) > 0)

           {

             //向文件中写信息

             fs.Write(buffer, 0, bytesRead);

           }

         }

 

         context.Response.ContentType = "text/plain" ;

         context.Response.Write( "上传成功" );

       }

       catch (Exception e)

       {

         context.Response.ContentType = "text/plain" ;

         context.Response.Write( "上传失败, 错误信息:" + e.Message);

       }

       finally

       { sr.Dispose(); }

 

     }

 

     public bool IsReusable

     {

       get

       {

         return false ;

       }

     }

   }

 

}

新建download.ashx

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Net;

 

namespace HCLoad.Web

{

   /// <summary>

   /// $codebehindclassname$ 的摘要说明

   /// </summary>

   public class download : IHttpHandler

   {

     private long ChunkSize = 102400; //100K 每次读取文件,只读取100K,这样可以缓解服务器的压力

 

     public void ProcessRequest(HttpContext context)

     {

       //string fileName = "123.jpg";//客户端保存的文件名

       String fileName = context.Request.QueryString[ "filename" ];

       string filePath = context.Server.MapPath( "Bubble.jpg" );

       System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

       if (fileInfo.Exists == true )

       {

         byte [] buffer = new byte [ChunkSize];

         context.Response.Clear();

         System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);

         long dataLengthToRead = iStream.Length; //获得下载文件的总大小

         context.Response.ContentType = "application/octet-stream" ;

         //通知浏览器下载文件而不是打开

         context.Response.AddHeader( "Content-Disposition" , "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));

         while (dataLengthToRead > 0 && context.Response.IsClientConnected)

         {

           int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize)); //读取的大小

           context.Response.OutputStream.Write(buffer, 0, lengthRead);

           context.Response.Flush();

           dataLengthToRead = dataLengthToRead - lengthRead;

         }

         context.Response.Close();

         context.Response.End();

       }

       //context.Response.ContentType = "text/plain";

       //context.Response.Write("Hello World");

     }

 

     public bool IsReusable

     {

       get

       {

         return false ;

       }

     }

   }

}

参考:
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/26/1554056.html
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
http://www.cnblogs.com/wmt1708/archive/2009/03/07/1405009.html
http://topic.csdn.net/u/20090918/10/5e41ab52-f514-46b5-ae6a-d69ddb197213.html
http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
http://www.cnblogs.com/gwazy/archive/2009/04/02/1427781.html
http://www.cnblogs.com/ewyb/archive/2009/12/10/1621020.html
http://blog.csdn.net/emily1900/archive/2010/06/08/5655726.aspx

dy("nrwz");

查看更多关于Silverlight文件上传下载实现方法(下载保存)的详细内容...

  阅读:70次