首页 > 编程 > C# > 正文

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

2020-01-24 01:23:52
字体:
来源:转载
供稿:网友

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; //因为要使用BitmapImageusing System.IO; //因为要使用Streamnamespace 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; //因为要用到Streamnamespace 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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表