Silverlight文件上传下载实现方法(下载保存)
search了非常多的文章,总算勉强实现了。有许多不完善的地方。
在HCLoad.Web项目下新建目录Pics复制一张图片到根目录下。
图片名:Bubble.jpg右击->属性->生成操作:Resource
UC_UpDown.xaml
<UserControlx: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"> <StackPanelBackground="White"Height="450"> <ButtonContent="down"Click="Button_Click"></Button> <HyperlinkButtonContent="下载保存"NavigateUri="http://localhost:4528/download.ashx?fileName=aa.txt"TargetName="_self"x:Name="lBtnDown"/> <TextBlockx:Name="tbMsgString"Text="下载进度"TextAlignment="Center"Foreground="Green"></TextBlock> <Buttonx:Name="btnDownload"Content="DownLoadPictures"Width="150"Height="35"Margin="15"Click="btnDownload_Click"/> <BorderBackground="Wheat"BorderThickness="5"Width="400"Height="280"> <Imagex:Name="imgDownLoad"Width="400"Height="300"Margin="15"Stretch="Fill"/> </Border> <Buttonx:Name="btnUpLoad"Content="UpLoadPictures"Width="150"Height="35"Margin="15"Click="btnUpLoad_Click"/> </StackPanel> </UserControl>
UC_UpDown.xaml.cs
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Net; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Documents; usingSystem.Windows.Input; usingSystem.Windows.Media; usingSystem.Windows.Media.Animation; usingSystem.Windows.Shapes; usingSystem.Windows.Media.Imaging;//因为要使用BitmapImage usingSystem.IO;//因为要使用Stream namespaceHCLoad { publicpartialclassUC_UpDown:UserControl { //1、WebClient对象一次只能启动一个请求。如果在一个请求完成(包括出错和取消)前,即IsBusy为true时,进行第二个请求,则第二个请求将会抛出NotSupportedException类型的异常 //2、如果WebClient对象的BaseAddress属性不为空,则BaseAddress与URI(相对地址)组合在一起构成绝对URI //3、WebClient类的AllowReadStreamBuffering属性:是否对从Internet资源接收的数据做缓冲处理。默认值为true,将数据缓存在客户端内存中,以便随时被应用程序读取 //获取选定图片信息 System.IO.FileInfofileinfo; publicUC_UpDown() { InitializeComponent(); } #region下载图片 privatevoidbtnDownload_Click(objectsender,RoutedEventArgse) { //向指定的Url发送下载流数据请求 StringimgUrl="http://localhost:4528/Bubble.jpg"; Uriendpoint=newUri(imgUrl); WebClientclient=newWebClient(); client.OpenReadCompleted+=newOpenReadCompletedEventHandler(OnOpenReadCompleted); client.DownloadProgressChanged+=newDownloadProgressChangedEventHandler(clientDownloadStream_DownloadProgressChanged); client.OpenReadAsync(endpoint); } voidOnOpenReadCompleted(objectsender,OpenReadCompletedEventArgse) { //OpenReadCompletedEventArgs.Error-该异步操作期间是否发生了错误 //OpenReadCompletedEventArgs.Cancelled-该异步操作是否已被取消 //OpenReadCompletedEventArgs.Result-下载后的Stream类型的数据 //OpenReadCompletedEventArgs.UserState-用户标识 if(e.Error!=null) { MessageBox.Show(e.Error.ToString()); return; } if(e.Cancelled!=true) { //获取下载的流数据(在此处是图片数据)并显示在图片控件中 //Streamstream=e.Result; //BitmapImagebitmap=newBitmapImage(); //bitmap.SetSource(stream); //imgDownLoad.Source=bitmap; StreamclientStream=e.UserStateasStream; StreamserverStream=(Stream)e.Result; byte[]buffer=newbyte[serverStream.Length]; serverStream.Read(buffer,0,buffer.Length); clientStream.Write(buffer,0,buffer.Length); clientStream.Close(); serverStream.Close(); } } voidclientDownloadStream_DownloadProgressChanged(objectsender,DownloadProgressChangedEventArgse) { //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上传图片 privatevoidbtnUpLoad_Click(objectsender,RoutedEventArgse) { /**/ /* *OpenWriteCompleted-在打开用于上传的流完成时(包括取消操作及有错误发生时)所触发的事件 *WriteStreamClosed-在写入数据流的异步操作完成时(包括取消操作及有错误发生时)所触发的事件 *UploadProgressChanged-上传数据过程中所触发的事件。如果调用OpenWriteAsync()则不会触发此事件 *Headers-与请求相关的的标头的key/value对** *OpenWriteAsync(Uriaddress,stringmethod,ObjectuserToken)-打开流以使用指定的方法向指定的URI写入数据 *Uriaddress-接收上传数据的URI *stringmethod-所使用的HTTP方法(POST或GET) *ObjectuserToken-需要上传的数据流 */ OpenFileDialogopenFileDialog=newOpenFileDialog() {//弹出打开文件对话框要求用户自己选择在本地端打开的图片文件 Filter="JpegFiles(*.jpg)|*.jpg|AllFiles(*.*)|*.*", Multiselect=false//不允许多选 }; if(openFileDialog.ShowDialog()==true)//.DialogResult.OK) { //fileinfo=openFileDialog.Files;//取得所选择的文件,其中Name为文件名字段,作为绑定字段显示在前端 fileinfo=openFileDialog.File; if(fileinfo!=null) { WebClientwebclient=newWebClient(); stringuploadFileName=fileinfo.Name.ToString();//获取所选文件的名字 #region把图片上传到服务器上 UriupTargetUri=newUri(String.Format("http://localhost:4528/WebClientUpLoadStreamHandler.ashx?fileName={0}",uploadFileName),UriKind.Absolute);//指定上传地址 webclient.OpenWriteCompleted+=newOpenWriteCompletedEventHandler(webclient_OpenWriteCompleted); webclient.Headers["Content-Type"]="multipart/form-data"; webclient.OpenWriteAsync(upTargetUri,"POST",fileinfo.OpenRead()); webclient.WriteStreamClosed+=newWriteStreamClosedEventHandler(webclient_WriteStreamClosed); #endregion } else { MessageBox.Show("请选取想要上载的图片!!!"); } } } voidwebclient_OpenWriteCompleted(objectsender,OpenWriteCompletedEventArgse) { //将图片数据流发送到服务器上 //e.UserState-需要上传的流(客户端流) StreamclientStream=e.UserStateasStream; //e.Result-目标地址的流(服务端流) StreamserverStream=e.Result; byte[]buffer=newbyte[4096]; intreadcount=0; //clientStream.Read-将需要上传的流读取到指定的字节数组中 while((readcount=clientStream.Read(buffer,0,buffer.Length))>0) { //serverStream.Write-将指定的字节数组写入到目标地址的流 serverStream.Write(buffer,0,readcount); } serverStream.Close(); clientStream.Close(); } voidwebclient_WriteStreamClosed(objectsender,WriteStreamClosedEventArgse) { //判断写入是否有异常 if(e.Error!=null) { System.Windows.Browser.HtmlPage.Window.Alert(e.Error.Message.ToString()); } else { System.Windows.Browser.HtmlPage.Window.Alert("图片上传成功!!!"); } } #endregion privatevoidButton_Click(objectsender,RoutedEventArgse) { //这种方法搞不定,好像提示跨域操作。 //提示:错误:UnhandledErrorinSilverlightApplication跨线程访问无效。 //UriupTargetUri=newUri(String.Format("http://localhost:4528/download.ashx?filename={0}","123.jpg"),UriKind.Absolute);//指定上传地址 //WebRequestrequest=WebRequest.Create(upTargetUri); //request.Method="GET"; //request.ContentType="application/octet-stream"; //request.BeginGetResponse(newAsyncCallback(RequestReady),request); //通过调用js代码下载,比较简单。 System.Windows.Browser.HtmlPage.Window.Eval("window.location.href='http://localhost:4528/download.ashx?filename=123.jpg';"); } voidRequestReady(IAsyncResultasyncResult) { MessageBox.Show("RequestComplete"); } } }
在HCLoad.Web项目下新建WebClientUpLoadStreamHandler.ashx
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Web; usingSystem.IO;//因为要用到Stream namespaceHCLoad.Web { publicclassWebClientUpLoadStreamHandler:IHttpHandler { publicvoidProcessRequest(HttpContextcontext) { //获取上传的数据流 stringfileNameStr=context.Request.QueryString["fileName"]; Streamsr=context.Request.InputStream; try { stringfilename=""; filename=fileNameStr; byte[]buffer=newbyte[4096]; intbytesRead=0; //将当前数据流写入服务器端文件夹ClientBin下 stringtargetPath=context.Server.MapPath("Pics/"+filename+".jpg"); using(FileStreamfs=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(Exceptione) { context.Response.ContentType="text/plain"; context.Response.Write("上传失败,错误信息:"+e.Message); } finally {sr.Dispose();} } publicboolIsReusable { get { returnfalse; } } } }
新建download.ashx
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Web; usingSystem.Web.Services; usingSystem.Net; namespaceHCLoad.Web { ///<summary> ///$codebehindclassname$的摘要说明 ///</summary> publicclassdownload:IHttpHandler { privatelongChunkSize=102400;//100K每次读取文件,只读取100K,这样可以缓解服务器的压力 publicvoidProcessRequest(HttpContextcontext) { //stringfileName="123.jpg";//客户端保存的文件名 StringfileName=context.Request.QueryString["filename"]; stringfilePath=context.Server.MapPath("Bubble.jpg"); System.IO.FileInfofileInfo=newSystem.IO.FileInfo(filePath); if(fileInfo.Exists==true) { byte[]buffer=newbyte[ChunkSize]; context.Response.Clear(); System.IO.FileStreamiStream=System.IO.File.OpenRead(filePath); longdataLengthToRead=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) { intlengthRead=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("HelloWorld"); } publicboolIsReusable { get { returnfalse; } } } }
参考:
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