views:

319

answers:

1

Hello, I am attempting to return a image from a server using Silverlight 3. The server returns the Response stream like this:

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

On the Silverlight client I am handling the stream like:

    Dim request As HttpWebRequest = result.AsyncState
    Dim response As HttpWebResponse = request.EndGetResponse(result)
    Dim responseStream As IO.Stream = response.GetResponseStream()

I want to take that stream and open the browsers save dialog, one option I have explored is using the Html.Window.Navigate(New Uri("image url")) and this opened the correct browser default dialog but it is not an option because I need to send extended information(e.g. XML) to the server through the HttpRequest.Headers.Item and the Navigate doesn't allow this.

How can I take a Response Stream and force the default browser Save dialog to appear from the Silverlight Application without using the Html.Window.Navigate(New Uri("image url"))?

+1  A: 

The straight answer is you can't, the Silverlight SaveFileDialog can only be opened as a direct result of a user interaction such as a button click.

The solution to this sort of issue (where you want an upload) is to Post the XML to the server for storage say in the session object or as file. The response is some handle you can use to retrieve the XML such as GUID.

You can then use a standard navigation placing the GUID in the query string of the URL. The receiving script (the ashx is this case) can retrieve the previously posted XML using the handle provided in the URL.

You'll also want to code the server-side response like this:-

context.Response.ContentType = imageFactory.ContentType;
context.Response.AddHeader("Content-Disposition", "attachment;file=someimage.jpg"); 
imgStream.WriteTo(context.Response.OutputStream);
imgStream.Close();

this will cause the browser to display an "Open or Save dialog". Normally the navigation state of the current window is maintained so you SL app should remain in its current state but I've not actually test that.

BTW, note no Response.End(), thats an awful thing to do, if you can avoid it then do so.

AnthonyWJones
Thanks, Anthony. This does work and the SL app does hold its current state. Question: What is the reason for not using Response.End()?
John Maloney
@John: Response.End() throws a ThreadAbortException and kills any further response processing including any post processing that might happen in Modules. Its much better to let the code come to its natural end than to summarily kill it off so dramatically.
AnthonyWJones