在Silverlight中打开响应流

3

我尝试使用Silverlight 3从服务器返回图像。服务器以以下方式返回响应流:

 context.Response.ContentType = imageFactory.ContentType
 imgStream.WriteTo(context.Response.OutputStream)
 imgStream.Close()
 context.Response.End()

在 Silverlight 客户端中,我处理流的方式如下:
    Dim request As HttpWebRequest = result.AsyncState
    Dim response As HttpWebResponse = request.EndGetResponse(result)
    Dim responseStream As IO.Stream = response.GetResponseStream()

我想要将流转化为浏览器保存对话框,我尝试过使用Html.Window.Navigate(New Uri("image url")),这样可以打开正确的浏览器默认对话框,但是我需要通过HttpRequest.Headers.Item发送扩展信息(例如XML)到服务器,而Navigate不允许这样做。如何在Silverlight应用程序中将响应流转化为浏览器的默认保存对话框而不使用Html.Window.Navigate(New Uri("image url"))?
1个回答

2
直截了当的答案是不行,Silverlight SaveFileDialog只能作为用户交互(例如按钮点击)的直接结果而打开。
这种问题的解决方案(如果你想要上传)是将XML发布到服务器进行存储,比如在会话对象或文件中。响应是一些句柄,你可以使用它来检索XML,例如GUID。
然后,你可以使用标准导航,在URL的查询字符串中放置GUID。接收脚本(在这种情况下是ashx)可以使用URL中提供的句柄检索先前发布的XML。
你还需要像这样编写服务器端响应:
context.Response.ContentType = imageFactory.ContentType;
context.Response.AddHeader("Content-Disposition", "attachment;file=someimage.jpg"); 
imgStream.WriteTo(context.Response.OutputStream);
imgStream.Close();

这将导致浏览器显示一个“打开或保存”对话框。通常,当前窗口的导航状态会保持不变,所以您的SL应用程序应该保持在当前状态,但我并没有实际测试过。

顺便说一下,注意不要使用Response.End(),那是非常糟糕的做法,如果可以避免,则请避免使用。


谢谢,安东尼。这确实有效,SL应用程序确实保持其当前状态。问题:不使用Response.End()的原因是什么? - John Maloney
@John:Response.End() 会抛出 ThreadAbortException 并终止任何进一步的响应处理,包括在模块中可能发生的任何后处理。让代码自然结束比突然将其彻底终止要好得多。 - AnthonyWJones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接