完全详解--Silverlight 下载文件
1:假设服务器端有文件test.rar:对应的地址是:http://localhost:34270/ClientBin/test.rar:
2:Silverlight要下载这个文件的方式很简单:使用HyperLinkButton就可以了:
<HyperlinkButton NavigateUri="http://localhost:34270/ClientBin/test.rar" Content="使用HyperLinkButton来下载test.rar" />
运行效果如下:
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之后再弹出保存按钮。
聪明的你能看出这段代码的问题吗??
运行结果如下:
错误是只能对UI线程执行操作,难道需要使用BeginInvoke??
OK,修改代码:
request.BeginGetResponse((responseAsyncCallBack) =>
{
this.Dispatcher.BeginInvoke(() =>
{ //code});
}, null);
继续运行,结果如下:
情况是这样的,微软为了保证对话框必须由用户启动,所以任何尝试使用委托,或代码的方式来弹出对话框都会抛出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,在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);
}
完整的代码如下:
/// <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);
}
}