Save File Dialog in Silverlight

This is not an original idea, but someone had asked this question on the Silverlight Forums and I couldn't find an answer written with ASP.NET so I thought it would be nice to provide a complete example here on my site.

Suppose you are generating a file in your Silverlight application and you would like to allow the user to save the file on their computer in the location of their choosing.

image

Currently, there is no mechanism that allows for this in Silverlight.  However, since Silverlight is hosted inside of a web browser, you can take advantage of the browser's capabilities.  This requires a little bit of Silverlight / HTML DOM interop, but nothing very fancy. 

In this example, I want to create a simple text file that the user can save on his/her computer.  I will create the data for the file in my Silverlight application and then I will pipe the data into the hosting HTML page.  Once the data has been piped into the hosting HTML page, I will programmatically submit the form that will post the data to DownloadFile.aspx.  This form will build the appropriate response (on the server-side) and prompt the user to save the file.

Silverlight Host Page
Notice the generateFileForm includes 2 hidden fields.  These are the fields that receive the data from the Silverlight application.

   1:  <body style="height:100%;margin:0;">
   2:      <form id="form1" runat="server" style="height:100%;">
   3:          <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
   4:          <div  style="height:100%;">
   5:              <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SLDownloadFile.xap" 
   6:              MinimumVersion="2.0.30523" Width="100%" Height="100%" />
   7:          </div>
   8:      </form>
   9:      <form id="generateFileForm" action="DownloadFile.aspx" method="post">
  10:          <input runat="server" type="hidden" id="downloadData" />
  11:          <input runat="server" type="hidden" id="fileName" />
  12:      </form>
  13:  </body>

Silverlight Root Visual CodeBehind
When the user clicks the button in the Silverlight application, the following event handler is fired.  At this point, we create our file data and pipe it to the hosting page using Silverlight HTML DOM Interop and programmatically submit the form called generateFileForm.

   1:  private void Button_Click(object sender, RoutedEventArgs e)
   2:  {
   3:      string myTextFile = "This is a a test";
   4:      HtmlDocument doc = HtmlPage.Document;
   5:      HtmlElement downloadData = doc.GetElementById("downloadData");
   6:      downloadData.SetAttribute("value", myTextFile);
   7:   
   8:      HtmlElement fileName = doc.GetElementById("fileName");
   9:      fileName.SetAttribute("value", "myFile.txt");
  10:      doc.Submit("generateFileForm");
  11:  }
 

DownloadFile.aspx CodeBehind

Once the form is posted, the Page_Load event handler will fire and the response will be built.

   1:  public partial class DownloadFile : System.Web.UI.Page
   2:  {
   3:      protected void Page_Load(object sender, EventArgs e)
   4:      {
   5:          string data = Request.Form["DownloadData"];
   6:          string fileName = Request.Form["FileName"];
   7:   
   8:          Response.Clear();
   9:          Response.ContentType = "application/octet-stream";
  10:          Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
  11:          Response.Write(data);
  12:          Response.Flush();
  13:          Response.Close();
  14:      }
  15:  }

Obviously, this is a wasteful approach since the data must be posted from the client to the server only to be downloaded by the client again so please keep this in mind.  Ideally, you would simply generate the file on the server side instead of inside the Silverlight application.  Furthermore, this solution is really only suitable for the smallest of files.  Enjoy!

Download Complete Source Here


Feedback

# re: Save File Dialog in Silverlight

Gravatar Yes. It's good that you wrote that. People use that question so often.. We used to say like you can use Response.BinaryWrite or Write but some people don't understand that..

Another way is that we can also use Naviage too.. Like we used to do in HTML or ASP.NET, we simply use hyperlink for that file. Depend on the browser config, it will show "Save File" dialog or open it in browser.. 7/18/2008 3:11 AM | Michael Sync

# re: Save File Dialog in Silverlight

Gravatar how about binary data?

only pass an file id to DownloadFile.aspx, then it internally find and send that file to the end user through browser? 7/18/2008 10:07 PM | unruledboy

# re: Save File Dialog in Silverlight

Gravatar unruledboy,
You could do it that way or if you still wanted to generate the file in your SL application, you could serialize the binary data to some format (like base-64) and transmit the data through the form post. As you might excpect, this would only be acceptable if the serialized data was very small. Thanks for the feedback. 7/19/2008 3:24 PM | Page Brooks





 

Please add 7 and 8 and type the answer here: