Silverlight 2 瀏覽器端儲存檔案

由於 Silverlight 2 是執行於一個與本機隔絕的 Sandbox 之中。微軟基於安全的原因在 Silverlight 2 並沒有提供任何 API,讓開發人員寫入資料至本機的檔案系統。但仍提供了openfiledialog 類別,以便從瀏覽器端運用對話方塊載入檔案。

所以目前只能將要存檔的內容,以 HTTP POST 送回至 Web Server,再由 Web Server 端觸發一個 ASP.NET 網頁,將欲存檔的內容以 application/octet-stream 型態以 ASP.NET Response 物件送回瀏覽器端。這一來一往傳送資料不是很有效率,但為了安全也成為目前唯一的方法了。

https://pagebrooks.com/archive/2008/07/16/save-file-dialog-in-silverlight.aspx

提供了一個 Silverlight 2 Beta 1 範例程式,我把它改成 Silverlight 2 Beta 2 版本,以便有興趣的朋友參考。首先用 Microsoft Silverlight Tools Beta 2 for Visual Studio 2008 預設之精靈產一個 Silverlight Web Application 的專案檔。並用 Microsoft Expression Blend 2.5 June 2008 Preview 版製作一個簡單介面,一個名為 btnDownloadFile 按鈕

image

接下來在這個 Host Silverlight 的 ASP.NET 網頁中加上下方藍色的隱藏的 Form 與欄位

<body style='height:100%;margin:0;'>
    <form id="form1" runat="server" style='height:100%;'>
            <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div  style='height:100%;'>
    <asp:Silverlight ID="Xaml1" runat="server" Source="".... 省略 </div>
    </form>
    <form id="generateFileForm" action="DownloadFile.aspx" method="post">
<input runat="server" type="hidden" id="DownloadData" />
<input runat="server" type="hidden" id="FileName" />
</form>
</body>

這個隱藏的 Form 與欄位當 Submit 時會將要寫入的檔案以 POST 送回到 Web Server 端,因此我們需要用 Visual Studio 2008 為此專案檔加入一個名為 DownloadFile.aspx 的 Web Form。

而在這個 DownloadFile.aspx 中,我們必須在 Page_Load 事件內立即將收到的檔案以 attachment 方式送回。只需要加入以下藍色的程式碼

protected void Page_Load(object sender, EventArgs e)
{
  string data = Request.Form["DownloadData"];
string fileName = Request.Form["FileName"];
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.Write(data);
Response.Flush();
Response.Close();

}

最後我們需要撰寫 Silverlight 2 的 btnDownloadFile 的事件處理函式,需要加上藍色的程式碼,並且記得用 Add Reference 將 System.Windows.Browser 這個組件加進專案中。這個範例就可以完成了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;

namespace DownloadFile
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }

        private void btnDownloadFile_Click(object sender, RoutedEventArgs e)
{
string myTextFile = "要儲存之檔案內容";
HtmlDocument doc = HtmlPage.Document;
HtmlElement downloadData = doc.GetElementById("DownloadData");
downloadData.SetAttribute("value", myTextFile);
HtmlElement fileName = doc.GetElementById("FileName");
fileName.SetAttribute("value", "myFile.txt");
doc.Submit("generateFileForm");
}
    }
}

附上 Visual Studio 2008 搭配 Microsoft Silverlight Tools Beta 2 for Visual Studio 2008 的範例程式。目前可以確定 Silverlight 2 不會提供直接寫入檔案到瀏覽器端的功能,在 2009年3月18日 MIX09 中,正式宣布 Silverlight 3 中將直接支援此一功能,但考量安全問題,必須透過使用者操作對話方塊形式,選取欲寫入的資料夾後,才可寫入檔案,開發人員仍不允許自由決定資料夾位置。

DownloadFile.zip