EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.

 

完全详解--Silverlight 下载文件

1:假设服务器端有文件test.rar:对应的地址是:http://localhost:34270/ClientBin/test.rar

clip_image002

 

2Silverlight要下载这个文件的方式很简单:使用HyperLinkButton就可以了:

<HyperlinkButton NavigateUri="http://localhost:34270/ClientBin/test.rar" 
                             Content="使用HyperLinkButton来下载test.rar" />

运行效果如下:

clip_image004

3:但是这种方法有个限制,假设我们要下载的文件是保存在数据库中呢?(本人严重反对将文件存在数据库中),或者是其他什么,能不能使用WebRequest来下载呢?

 

当然能!!

 

4:首先在前台添加下载按钮代码:

<Button Content="使用WebRequest来下载" Click="Download_Click" />

 

后台代码如下:

 

private void Download_Click(object sender, RoutedEventArgs e)
{
    string filePath = "http://localhost:34270/ClientBin/test.rar";

    WebRequest request = WebRequest.Create(filePath);

    request.BeginGetResponse((responseAsyncCallBack) =>
    {
        SaveFileDialog sfd = new SaveFileDialog();

        string extension = System.IO.Path.GetExtension(filePath);

        sfd.Filter = string.Format("*{0}| *{0}", extension);

        if (sfd.ShowDialog() == true)
        {

            Stream openFileStream = sfd.OpenFile();

            #region 获取response bytes

            WebResponse response = request.EndGetResponse(responseAsyncCallBack);
            Stream responseStream = response.GetResponseStream();

            Byte[] bufferBytes = new Byte[responseStream.Length];

            responseStream.Read(bufferBytes, 0, bufferBytes.Length);

            #endregion

            openFileStream.Write(bufferBytes, 0, bufferBytes.Length);
            openFileStream.Flush();

        }

    }, null);

}

 

因为request.BeginGetResponse是异步的,所以在获取Response之后再弹出保存按钮。

 

聪明的你能看出这段代码的问题吗??

 

 

 

 

 

 

运行结果如下:

clip_image006

错误是只能对UI线程执行操作,难道需要使用BeginInvoke??

 

 

 

 

OK,修改代码:

request.BeginGetResponse((responseAsyncCallBack) =>

                {

                    this.Dispatcher.BeginInvoke(() =>

                        { //code});

                }, null);

 

继续运行,结果如下:

 

clip_image008

 

情况是这样的,微软为了保证对话框必须由用户启动,所以任何尝试使用委托,或代码的方式来弹出对话框都会抛出SecurityException.

 

那么如何做呢?

 

 

 

首先SaveFileDialog必须在Download_Click事件里面,这样才不会抛出SecurityException.

所以在WebRequest request = WebRequest.Create(filePath);的后面增加代码:

//判断是否需要下载
 bool needDownload = false;

 SaveFileDialog sfd = new SaveFileDialog();

 string extension = System.IO.Path.GetExtension(filePath);

 sfd.Filter = string.Format("*{0}| *{0}", extension);


 if (sfd.ShowDialog() == true)
 {
     needDownload = true;
 }

 

接着修改BeginGetResponse,在needDownloadtrue的时候开始下载文件:

 

if (needDownload)

            {

                request.BeginGetResponse((responseAsyncCallBack) =>

                    {

                        this.Dispatcher.BeginInvoke(() =>

                            {

                                using (Stream openFileStream = sfd.OpenFile())

                                {

                                    #region response bytes

 

                                    WebResponse response = request.EndGetResponse(responseAsyncCallBack);

                                    Stream responseStream = response.GetResponseStream();

 

                                    Byte[] bufferBytes = new Byte[responseStream.Length];

                                    responseStream.Read(bufferBytes, 0, bufferBytes.Length);

 

                                    #endregion

 

                                    openFileStream.Write(bufferBytes, 0, bufferBytes.Length);

                                    openFileStream.Flush();

                                }

                            });

                    }, null);

            }

 

 

完整的代码如下:

 

/// <summary>

        ///

        /// </summary>

        private void Download_Click(object sender, RoutedEventArgs e)

        {

            string filePath = "http://localhost:34270/ClientBin/test.rar";

 

            WebRequest request = WebRequest.Create(filePath);

 

            //

            bool needDownload = false;

 

            SaveFileDialog sfd = new SaveFileDialog();

 

            string extension = System.IO.Path.GetExtension(filePath);

            sfd.Filter = string.Format("*{0}| *{0}", extension);

 

            if (sfd.ShowDialog() == true)

            {

                needDownload = true;

            }

 

            if (needDownload)

            {

                request.BeginGetResponse((responseAsyncCallBack) =>

                    {

                        this.Dispatcher.BeginInvoke(() =>

                            {

                                using (Stream openFileStream = sfd.OpenFile())

                                {

                                    #region response bytes

 

                                    WebResponse response = request.EndGetResponse(responseAsyncCallBack);

                                    Stream responseStream = response.GetResponseStream();

 

                                    Byte[] bufferBytes = new Byte[responseStream.Length];

                                    responseStream.Read(bufferBytes, 0, bufferBytes.Length);

 

                                    #endregion

 

                                    openFileStream.Write(bufferBytes, 0, bufferBytes.Length);

                                    openFileStream.Flush();

                                }

                            });

                    }, null);

            }

        }

posted @ 2011-07-10 06:13  LoveJenny  阅读(6598)  评论(17编辑  收藏  举报
EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.