繞過silverlight的安全限制的js和asp教程.net上傳檔案方法
1.silveright頁面按鈕調用承載頁的js代碼開啟一個用於上傳的aspx頁面,檔案的上傳都是在這個頁面中完成。
2.檔案上傳完成以後,上傳頁將上傳的檔案的檔案名稱傳回承載頁,再由承載頁傳回silverlight,以完成其它的工作。
具體實現如下:
1.首先這個方法需要silverlight與承載頁的js代碼進行互動,所以必須完成以下的基礎操作:
1 void FileUploader_Loaded(object sender, RoutedEventArgs e)
2 {
3 HtmlPage.RegisterScriptableObject("FileUploadCtrl", this);
4 }
在需要調用承載頁的loaded事件中將本silverlight頁面註冊為指令碼對象,這樣承載頁中的js代碼就可以使用本頁的後台代碼中具有ScriptableMember特性的方法了,如以下方法:
1 [ScriptableMember]
2 public void SetSelectedFile(string fullName)
3 {
4 SelectedFileName = fullName;
5 }
這個方法是給承載頁的js代碼將上傳檔案的檔案名稱傳回silverlight。
在承載中定義如下的函數
1 function UploadFile() {
2 //開啟檔案上傳頁面
3 window.open('FileUpload.aspx', '上傳附件', 'height=30,width=300, toolbar=no, menubar=no,location=no, status=no');
4 }
5 function SetSelectedFile(fullname) {
6 //將上傳檔案的檔案名稱傳回silverlight
7 var control = document.getElementById("SilverlightControl");
8 var manager = control.Content.FileUploadCtrl;
9 manager.SetSelectedFile(fullname);
10 }
11 function OpenAffix(msg) {
12 //開啟檔案
13 if (arguments.length > 0) {
14 window.open("UploadFiles/" + arguments[0], "_blank");
15 }
16 }
2.完成以上工作以後則可以進行以下的操作。
在頁面中放一個按鈕,點擊事件這麼寫:
1 public void Button_Click(object sender, RoutedEventArgs e)
2 {
3 try
4 {
5 ScriptObject sobjUploadFile = HtmlPage.Window.GetProperty("UploadFile") as ScriptObject;
6 sobjUploadFile.InvokeSelf();
7 return;
8 }
9 catch (Exception ex)
10 {
11 MessageBox.Show(ex.Message);
12 }
13 }
第5行中GetProperty的參數即為承載頁定義的js函數的函數名。運行這段代碼就可以調用承載頁的UploadFile的方法,即開啟FileUpload.aspx頁面。
3.FileUpload.aspx頁面的內容如下:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUpload.aspx.cs" Inherits="OIU.Web.FileUpload" %>
2
3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml">
6 <head runat="server">
7 <title></title>
8 <script type="text/網頁特效">
9 function SetSelectedFile(fullName) {
10 window.opener.location = "javascript:SetSelectedFile('" + fullName + "');";
11 window.close();
12 }
13 </script>
14 </head>
15 <body>
16 <form id="form1" runat="server">
17 <div>
18 <asp:FileUpload runat="server" ID="fu" />
19 <asp:Button Text="上傳" runat="server" ID="btnUpload"
20 onclick="btnUpload_Clicked" />
21 </div>
22 </form>
23 </body>
24 </html>
這裡注意,第9行的js函數,通過window.opener來調用開啟這個頁面的父頁面的js方法:SetSelectedFile。
上傳按鈕的點擊事件處理函數這麼寫:
1 protected void btnUpload_Clicked(object sender, EventArgs e)
2 {
3 if (fu.HasFile)
4 {
5 if (fu.PostedFile.ContentLength / 1024 / 1024 > 5)
6 {
7 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>alert('檔案過大,支援最大5M的檔案上傳');</script>");
8 return;
9 }
10 //string uploadFullName = string.Format("{0}UploadFiles{1}", AppDomain.CurrentDomain.BaseDirectory, fu.FileName);
11 string uploadFullName = Server.MapPath("~/UploadFiles/") + fu.FileName;
12 fu.SaveAs(uploadFullName);
13 //將檔案全路徑返回父頁面
14 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>SetSelectedFile('" + fu.FileName + "');</script>");
15 }
16 else
17 {
18 ClientScript.RegisterStartupScript(ClientScript.GetType(), "myscript", "<script>alert('新先選擇要上傳的檔案');</script>");
19 }
20 }
21 }
裡面有一部分的驗證操作。開始我是想將上傳的全路徑傳給頁面再傳回silverlight的,但是,從後台調用前台js函數時參數的路徑分隔字元全被轉義了,如果誰能解決這個問題,可以跟帖讓我學習學習。
4.完成了以上的操作以後,檔案就已經上傳到了伺服器指定的目錄了,接下來的工作就是如何下載或者開啟上傳的檔案。
我的實現方法是通過silverlight頁面文本的點擊,調用承載頁的OpenAffix函數使用開啟檔案。具體實現如下:
1 private void StatusText_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
2 {
3 if (null != StatusText.Tag && !string.IsNullOrEmpty(StatusText.Tag.ToString()))
4 {
5 HtmlPage.Window.Invoke("OpenAffix", StatusText.Tag);
6 }
7 }
這是另一種silverlight調用承載頁js函數的方法。參考第1條中js函數,可以實現檔案的下載或者開啟