search了非常多的文章,总算勉强实现了。有许多不完善的地方。 在HCLoad.Web项目下新建目录Pics复制一张图片到根目录下。 图片名:Bubble.jpg 右击->属性->生成操作:Resource



search了非常多的文章,总算勉强实现了。有许多不完善的地方。

在HCLoad.Web项目下新建目录Pics复制一张图片到根目录下。

图片名:Bubble.jpg 右击->属性->生成操作:Resource

UC_UpDown.xaml


Silverlight文件上传下载(下载保存)_hiveSilverlight文件上传下载(下载保存)_Silverlight_02大气象


<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


Silverlight文件上传下载(下载保存)_hiveSilverlight文件上传下载(下载保存)_Silverlight_02大气象


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


Silverlight文件上传下载(下载保存)_hiveSilverlight文件上传下载(下载保存)_Silverlight_02大气象


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

Silverlight文件上传下载(下载保存)_hiveSilverlight文件上传下载(下载保存)_Silverlight_02大气象


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;

            }

        }

    }

}