原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章來源 、作者信息和本聲明。否則將追究法律責任。
最近在做一個大文件斷點續傳的控件,有試過純C#的代碼來寫,但后來發現是在是太不靈活了,於是考慮使用控件。但在控件開發過程中發現,如何獲取上傳文件的物理路徑是個大問題,因為Silverlight不支持獲取客戶端路徑的,不僅是Silverlight,所有的微軟上傳控件都不支持獲取本地物理路徑。於是我就各種查,終於發現有種方法可以獲取到文件的信息了。
先看一個例子

1 #region 選擇文件 2 private void bt_SelectFile_Click(object sender, RoutedEventArgs e) 3 { 4 OpenFileDialog ofd = new OpenFileDialog(); //初始化 5 ofd.Multiselect = true; //設置可以多選 6 ofd.Filter="請選擇文件|‘*’"; //限制文件類型及提示 7 if (ofd.ShowDialog() == true) 8 { 9 foreach (FileInfo file in ofd.Files) 10 { 11 UserFile userFile = new UserFile(); //自定義的文件上傳信息類 12 userFile.FileName = file.Name; //獲取文件名 13 userFile.FileStream = file.OpenRead(); //以只讀的方式打開文件 14 userFile.FilePhysicalpath = file.FullName; //在由受信任的應用程序調用時,獲取目錄或文件的完全路徑名 15 userFile.FileTime = file.LastWriteTime; //在由受信任的應用程序調用時,獲取文件的最后修改日期 16 } 17 } 18 } 19 #endregion
事實上,在我們調試的時候會發現,userFile.FilePhysicalpath = file.FullName; userFile.FileTime = file.LastWriteTime; 這兩句代碼會報錯,提示說發現未經調試的異常。這是因為Silverlight在由微軟的封裝下不允許訪問客戶端的文件,怎么解決呢?其實很簡單,在最新發布的Silverlight5的版本中,微軟允許開發者在內部通過提升應用程序的信任度來獲取本地文件操作的權限。
右擊我們的Silverlight項目的屬性,在Silverlight一欄下,我們可以看到
勾選【在瀏覽器內運行時需要提升的信任】,這樣我們就可以操作本地文件啦!
這里需要說明一下在勾選了之后微軟做的操作,因為有的時候我們勾選了還是不能獲取文件的路徑。
當你勾選“在瀏覽器內運行時需要提升的信任”時,visual studio會做下面幾件事情:
1、在silverlight的項目文件(.csproj)中增加內容:<RequireInBrowserElevation>true</RequireInBrowserElevation>
2、在項目的Properties文件夾中增加一個文件:InBrowserSettings.xml。
3、在silverlight的項目文件(.csproj)中增加內容:<InBrowserSettingsFile>Properties/InBrowserSettings.xml</InBrowserSettingsFile>
詳細情況請看我的另一篇文章Silverlight控件——如何提升應用程序信任度與問題解決
接下來我們將說明如何部署受信應用,首先,要使受信應用在遠程客戶機上被訪問,必須對xap進行簽名。
進入TrustedApp項目屬性,轉到簽名頁,勾選“為Xap文件簽名”,這里我們將創建一個新的測試證書,以此進行演示,實際項目中可以向證書頒發機構申請信任證書,當然這是需要$的。單擊創建新測試證書按鈕,在彈出對話框中輸入密碼,這里設置為test,確定后,Visual Studio將創建一個證書文件,默認保存在項目根目錄下。
8 接下來單擊“從存儲區選擇”按鈕,在彈出窗口中選擇剛才創建的證書
9 在簽名頁面,單擊“更多詳細信息”按鈕,將會顯示證書的詳細信息,選擇詳細信息標簽,然后單擊“復制到文件”按鈕,進入證書導出向導:
進入以下頁面后,選擇不要導出私鑰:
此步驟導出的證書供客戶端使用!
10 完成后重新生成解決方案
11 將受信應用部署到IIS,部署與傳統ASP.NET應用一樣,無需做其他設置。
12 以上基本完成了服務端的設置,接下來對於客戶端需要做一些設置,才能在瀏覽器內運行受信應用
13 首先需要啟用瀏覽器內受信應用權限,這可直接通過修改注冊表來完成:
注冊表路徑:HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight
值名稱:AllowElevatedTrustAppsInBrowser
值類型:DWORD
可用值:不可在瀏覽器內運行受信應用,設置為0,如果啟用設置為1
[注:如果沒有在話,右鍵新建一個]
14 在客戶端安裝第9步驟導出的證書,在證書文件上單擊右鍵,選擇安裝,進入證書安裝向導,選擇存儲區時,將證書導入到“受信任的發布者”位置:
15 重復第14步驟,選擇存儲區時,將證書導入到“受信任的根證書頒發機構”位置。
16 到此,我們即可在此客戶端上運行受信應用了(注意下圖中的地址已經是非本機地址):
17 但是,必須注意此時的Silverlight是沒辦法自動更新的,也就是說服務端xap更新后,客戶端重新訪問時不會去自動下載xap,這顯然不符合需求,那該怎么做呢?我們需要在每次生成xap的時候,自動對xap進行時間戳簽名。
18 進入到TrustedApp項目屬性,選擇生成事件:
在后期生成事件命令行中輸入以下命令,進行xap的時間戳簽名:
1 "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\signtool.exe" sign /v /f "$(ProjectDir)TrustedApp_1_TemporaryKey.pfx" /p test /t http://timestamp.comodoca.com/authenticode $(TargetName).xap
前面為signtool的全路徑,它通常位於所安裝的Windows SDK目錄下,
/f 后面跟隨證書的全路徑,以上示例表示當前項目下的TrustedApp_1_TemporaryKey.pfx證書文件,
/p 后面表示證書的密碼,
/t 后面跟隨一個CA Authenticode Timestamping Service的URL地址,命令最后部分為需要簽名的xap文件。
進行此步操作后,每次生成xap文件后,Visual Studio將自動調用次命令進行xap的時間戳簽名。這樣,客戶端重新訪問網頁時,即可自動下載更新xap。
現在我們就可以在測試的時候獲取到文件的路徑啦。
好了,我們把項目發出到服務器上面去看看吧,咦?怎么還是獲取不到呢?原來這是因為調試的時候是在本地,而發不到服務器上之后,是通過互聯網訪問的,也就是說,這是一個跨域的行為。聰明的你肯定想到了,對了,我們在編寫一個可以跨域訪問的腳本就行了撒。其實很簡單,看下面
在我們的web項目下建立一個clientaccesspolicy.xml,代碼如下:

1 <?xml version="1.0" encoding="utf-8"?> 2 <access-policy> 3 <cross-domain-access> 4 <policy> 5 <allow-from http-request-headers="*"> 6 <domain uri="*"/> 7 </allow-from> 8 <grant-to> 9 <resource path="/" include-subpaths="true"/> 10 </grant-to> 11 </policy> 12 </cross-domain-access> 13 </access-policy>
將 clientaccesspolicy.xml 文件保存到承載該服務的域的根目錄中。例如,如果該服務在 http://fabrikam.com 上承載,則文件必須位於 http://fabrikam.com/clientaccesspolicy.xml。
另外再建立一個crossdomain.xml,代碼如下:

1 <?xml version="1.0"?> 2 <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> 3 <cross-domain-policy> 4 <allow-http-request-headers-from domain="*" headers="*"/> 5 </cross-domain-policy>
將 crossdomain.xml 文件保存在承載服務的域的根目錄中。例如,如果該服務在 http://fabrikam.com 上承載,則文件必須位於 http://fabrikam.com/crossdomain.xml。
詳情請看使服務跨域邊界可用
現在我們就可以在其他電腦打開網站輸入網址,獲取到我們本地文件的路徑了。