Silverlight结合Web Service进行文件上传

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.youkuaiyun.com/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.youkuaiyun.com/emily1900/archive/2010/06/08/5655726.aspx

凡事以大气象去面对,优秀是一种习惯。

 
分类:  SilverLight
标签:  Silverlight

转载于:https://www.cnblogs.com/meimao5211/p/3466545.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值