Silverlight文件上传下载实现方法(下载保存)
程序员文章站
2022-11-22 12:05:08
search了非常多的文章,总算勉强实现了。有许多不完善的地方。
在hcload.web项目下新建目录pics复制一张图片到根目录下。
图片名:bubble.jpg...
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; } } } }
参考:
上一篇: jQuery实现的*跑动效果示例
下一篇: 6行代码实现微信小程序页面返回顶部效果