完全详解--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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?