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

(0)

相关推荐

  • JavaWeb实现多文件上传及zip打包下载

    本文实例为大家分享了javaweb多文件上传及zip打包下载的具体代码,供大家参考,具体内容如下 项目中经常会使用到文件上传及下载的功能.本篇文章总结场景在JavaWeb环境下,多文件上传及批量打包下载功能,包括前台及后台部分. 首先明确一点: 无法通过页面的无刷新ajax请求,直接发下载.上传请求.上传和下载,均需要在整页请求的基础上实现.项目中一般通过构建form表单形式实现这一功能. 一.多文件上传 项目需求为实现多图片上传功能.参考测试了网上找到的众多插件方法后,决定选用Jquery原始

  • JavaScript判断文件上传类型的方法

    本文实例展示了JavaScript判断文件上传类型的方法,是一个非常常用的技巧.具体实现方法如下: 文件上传时用到一个功能,使用html元素的input标签实现: <input id="imageFile" name="imageFile1" accept="image/jpg,image/jpeg,image/png,image/bmp,image/gif" type="file" title="点击选择文件

  • Asp.NET控制文件上传的大小方法(超简单)

    在web.config中的system.web 节点下添加如下代码: 第2行的maxRequestLength="8192",这里限制最大为8MB,可以自行设置.executionTimeout="800",executionTimeout预设(即默认)是 90 秒 <system.web> <httpRuntime maxRequestLength="8192" executionTimeout="800"

  • JavaScript大文件上传的处理方法之切片上传

    目录 前言 切片后上传 生成hash 文件秒传 暂停上传 中断请求示例 添加暂停上传功能 恢复上传 添加功能总结 前言 本篇介绍了切片上传的基本实现方式(前端),以及实现切片上传后的一些附加功能,切片上传原理较为简单,代码注释比较清晰就不多赘述了,后面的附加功能介绍了实现原理,并贴出了在原本代码上的改进方式.有什么错误希望大佬可以指出,感激不尽. 切片后上传 切片上传的原理较为简单,即获取文件后切片,切片后整理好每个切片的参数并发请求即可. 下面直接上代码: HTML <template> &

  • selenium+python实现文件上传操作的方法实例

    前言 selenium处理文件上传大致会有两种情况,一种是文件上传使用的是input标签元素,即<input type="file">,那么对这个input标签元素使用sendkeys方法输入文件的路径就可以完成上传,另一种是调用windows系统完成文件上传,即文件上传会弹出windows弹窗,此时则需要借助Autoit这样一个小工具结合selenium完成. 方法如下 1.文件上传使用的是input标签元素,selenium+python代码示例参考如下: import

  • Serv-U中禁止某类文件上传的设置方法

    一.禁止某类文件上传 在用户的"目录访问"那里添加一条访问规则,路径设置为 *.exe ,取消所有的权限,并把这个规则放在最上面的位置. Path=*.exe Access=--– 这样处理后,该用户就不能在自己的目录上传*.exe的文件了,同时目录下面的*.exe文件也不会被列出来,也不能修改已经上传的文件后缀为exe.在Serv-U 6版本中测试正常. 二.只允许某类文件上传 1.在用户的"目录访问"那里添加一条访问规则,路径设置为 *.html,设置 读取.写

  • php文件上传简单实现方法

    本文实例讲述了php文件上传的简单实现方法.分享给大家供大家参考.具体如下: 文件1:index.php 复制代码 代码如下: <form enctype="multipart/form-data" action="uploadProcess.php" method="post" name="myform"> 用户名:<input type="text" name="userna

  • php中关于普通表单多文件上传的处理方法

    然而有些情况只需要传递几个文件,而且文件体积并不太大,这种情况下使用组件则有点牛刀杀鸡的感觉,通过html自带的<input type="file">表单就可以实现需要的功能,关键在于后台接收程序的处理. php处理上传做的很方便,上传文件的信息通过服务器自动处理到$_FILES数组中,开发者只需要使用的内置处理函数简单操作就可以啦.ASP开发者则没有这么幸运,官方并没有提供直接的处理方法,需要开发者自己设计,这时就需要开发者了解IIS对enctype="mult

  • Spring Boot搭建文件上传服务的方法

    本文实例为大家分享了Spring Boot搭建文件上传服务的具体代码,供大家参考,具体内容如下 一.服务端 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http:/

  • 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"

随机推荐