这两天被silverlight的文件下载搞死了!~~~网上找的一堆全是通过异步去下载文件流,通过已知的文件在服务器端的地址,但实际项目应用中
出于安全考虑很多中小型文件还是通过大对象存储在数据中的!~~ 下面通过两个例子和大家分享 silverlight的大对象文件下载!~
一。直接在silverlight客户端下载文件
在silverlight客户端提示用户下载文件,采用SaveFileDialog 控件,该控件是先生成文件再往文件中写入文件流,但缺点是SaveFileDialog的
SafeFileName 是只读的,在弹出来的下载提示框中要求用户输入要保存的文件名,这样的用户体验就非常的不爽了!~
代码如下:
#region silverlight下载代码
SaveFileDialog sf = new SaveFileDialog();
sf.SafeFileName
//由于 SafeFileName 是只读的,但要保证用户下下来的文件类型和和原来文件类型是一致,否则文件就不能用
string extent = Path.GetExtension(Info.AttachFileName);//Info 是一个对象,AttachFileName 是要下载的文件全名,这里是获取原文件的后缀,用的时候换成自己的存储的文件名,以下出现的Info 都是我自己用的实体类
string extension = string.Format("(*{0})|*{1}|所有文件 (*.*)|*.*", extent, extent);
if (string.IsNullOrEmpty(extent))
{
extension = "Word文件 (*.docx)|*.docx|zip压缩文件 (*.zip)|*.zip|所有文件 (*.*)|*.*";
}
sf.DefaultExt = extension;
sf.Filter = extension;
sf.FilterIndex = 1;
if (sf.ShowDialog() != true) return;
Stream clientStream = sf.OpenFile();
using (Stream serverStream = new MemoryStream(Info.AttachFile))//Info 是一个对象,AttachFile 是byte[] 类型,是文件字节数组
{
byte[] buffer = new byte[serverStream.Length];
serverStream.Read(buffer, 0, buffer.Length);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Close();
}
#endregion
二。silverlight结合asp.net的文件实现下载
1.silverlight.xaml代码
<Button Content="下载" Click="FileButtonClick" x:Name="fileButton" />
2. silverlight.xaml.cs 代码
var goToPage = HtmlPage.Window.GetProperty("SilverlightFileDownLoad") as ScriptObject;
if (goToPage != null)
goToPage.InvokeSelf(string.Format("SilverlightFile.ashx?id={0}", Info.Id.ToString()));//调用Default.aspx页面的js方法
3.Default.aspx 的JS 函数
// silverlight调用实现文件下载
function SilverlightFileDownLoad(message) {
window.open('SilverlightFileDownLoad/' + message);
}
4.在web网站中添加 SilverlightFileDownLoad/SilverlightFile.ashx 文件
public void ProcessRequest(HttpContext context)
{
try
{
//获取从silverlight传过来的ID参数
string idString = context.Request.QueryString["id"];
if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(idString))
{
int id = Convert.ToInt32(idString);
String fileName = null;
Stream iStream = null;
long dataLengthToRead = 0;//获得下载文件的总大小
#region 从底层查出对象详细
GroupQuailtyNotice info = _iGroupQuailtyNoticeBLL.GetById(id);
fileName = info.AttachFileName;
iStream = new MemoryStream(info.AttachFile);//AttachFile 为 byte[] 数组
dataLengthToRead = info.AttachFile.Length;
#endregion
#region 页面输出下载
if (iStream != null)
{
byte[] buffer = new byte[ChunkSize];
context.Response.Clear();
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(102400));//读取的大小
context.Response.OutputStream.Write(buffer, 0, lengthRead);
context.Response.Flush();
dataLengthToRead = dataLengthToRead - lengthRead;
}
context.Response.Close();
context.Response.End();
}
#endregion
}
}
catch (System.Exception ex)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
经过以上步骤就能实现像ASP.NET下载文件那样,提示文件下载,并自动保存原文件了!!!