当前位置: 移动技术网 > IT编程>开发语言>c# > Silverlight文件上传下载实现方法(下载保存)

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

2019年07月18日  | 移动技术网IT编程  | 我要评论

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;
      }
    }
  }
}

参考:







如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网