莫名其妙的Silverlight資源檔引用問題

來源:互聯網
上載者:User
問題描述

最近項目中遇到一個和資源檔相關的很奇怪的問題。有一個Silverlight應用會根據當前Url中的某個特定參數來決定使用什麼文化的資源檔(關於資源的檔案的使用見Silverlight 2 RTM 多國語言支援)。在其他機器上運行沒有問題,傳入zh-Hans和en-US介面都能正確顯示相應語言的文字。但是在我的系統上卻不管傳入什麼都是顯示的英文文字。

問題分析

開啟工程看了一下,在資源檔夾下只定義了兩個資源,一個是主資源XXX.resx,一個是英文中立資源XXX.en.resx。編譯之後,主資源會被打包到主程式集中,而其他資源則被編譯成獨立的程式集,稱為衛星程式集。Silverlight代碼中在提取Url參數的時候也加上了一個檢測邏輯,就是如果傳入的語言不是英文,那麼就使用zh-Hans。也就是說在其他人的機器上,如果你輸入了fr,那麼也是顯示中文。分析加調試弄了好一會之後,我判定應該不是程式碼的bug。因為在某些人的機器上是正常的,而在我的機器還有另外一個同事的機器上卻不正常,而且問題是可重現的。這說明了問題和本地環境有關。

清緩衝,清Silverlight隔離儲存區 (Isolated Storage)之後發現問題依然存在。難道是作業系統的問題?!我用的是win7,同事用的是win2008,都是高版本的windows,而其他人用的不是xp就是2003。為了證實我的想法,我又找了一台2008的機器,測試結果和我機器上的一樣。看來很有可能問題就在這。可是,為什麼呢?

為了尋找問題的原因,我重新查閱了一下Silverlight使用資源檔的相關材料(和DotNet其實差不多)。

Silverlight的資源尋找方式

Silverlight採用中心輻射型結構來打包和部署資源檔程式集。圍繞在中心的是主程式集裡面的資源,這個資源也被稱為中立或者預設資源。如果主程式集沒有顯式設定語言,那麼一個資源要是尋找失敗,最終會使用主程式集中的資源。每個輻射點指向的是每一種語言對應的衛星程式集。

Silverlight在尋找資源檔的時候採用了如下的方式:

最頂級是應用程式的預設程式集。第二級是語言相關程式集,它代表的是地區無關的語言文化,如英文,簡體中文,繁體中文(zh-Hant)等;第三級是和地區相關的文化程式集,如美國英語,英國英語,大陸簡體中文,新加坡簡體中文。Silverlight在載入本地資源的時候首先會根據CultureInfo.CurrentUICulture屬性來判斷應該載入哪一種文化對應的資源。在尋找的時候是按照上面的階層從下到上進行尋找的。具體說來,當ResourceManager在尋找一個資源時會經過以下幾個步驟:

1. 尋找具體語言相應的程式集是否存在。如設定了zh-CN,那麼就尋找XXX.zh-CN.resx資源檔是否存在(存在於衛星程式集中),如果程式集不存在或者在該程式集中找不到此資源的定義,那麼尋找失敗。如果作業系統支援回溯(Fallback)邏輯,那麼跳到第二步;否則跳到第三步。

2. 作業系統提供一份推薦的語言回溯清單,上麵包含了具體語言文化字串(如en-US)和相應的中立語言字串(如en)。Resource Manager會根據這份清單去尋找相應的衛星程式集和程式集內指定資源是否存在。如果尋找失敗,則跳到下一步。

3. 如果上面兩步都失敗,那麼尋找此具體文化的上一級文化的衛星程式集,也就是地區無關的文化,例如en-US尋找失敗,則尋找en是否存在。

4. 如果上面3步都失敗的話,那麼Silverlight會查看主程式集的NeutralResourcesLanguageAttribute屬性。NeutralResourcesLanguageAttribute是用在程式集上的屬性,它是用來告知ResourceManager,某個程式集使用的語言是什麼。ResourceManager會查看此屬性的值,看是否滿足條件。如果主程式集沒有指定此屬性,那麼將會使用主程式集中的資源作為預設資源。

5. 如果第4步也尋找失敗,那麼ResourceManager將使用文化無關(Invarient Culture)的資源。

問題所在

在網上查到MSDN的文章說,自打Vista開始,作業系統開始支援這種“Fallback”的邏輯了。通過系統API GetThreadPreferredUILanguages可以擷取作業系統核心推薦使用的語言清單。

由於工程裡面並沒有指定zh-Hans的資源檔(於是也就沒有zh-Hans的衛星程式集),也沒有設定主程式集使用的語言是什麼(通過NeutralResourcesLanguageAttribute屬性指定)因此在第一步的時候尋找失敗;這個時候,在我win7的機器上,由於作業系統支援fallback邏輯,因此Silverlight會使用作業系統提供的語言清單去尋找,由於我的系統是中文系統,因此清單上第一項肯定是zh-CN,接下來的猜測應該是en-US和en(老美搞的作業系統嘛,當然要把自家語言排前一點了)。尋找zh-CN肯定又失敗,但是尋找en卻能夠找到,因此就出現了不管你參數中輸入什麼語言文化字串,都會顯示英文。

而在其他低版本的windows上,因為作業系統不支援這份清單,那麼Silverlight始終沒有辦法找到zh-Hans相關的衛星程式集,而主程式集又沒有顯式的設定語言,因此ResourceManager就會使用主程式集裡面的資源檔,也就是中文。

這就是為什麼在低版本windows上,亂輸入語言,顯示的預設是中文,而在Vista等高版本windows上,預設顯示的是英文的緣故。

再插一句,如果在主程式集中顯式設定了NeutralResourcesLanguageAttribute為zh-Hans,然後在低版本的windows上訪問此應用程式的時候輸入例如fr等不支援的語言,那麼Silverlight將會使用語言無關的資源(語言無關的資源具體被定義在哪不是很確定,可能是dotnet類庫,也可能是本地作業系統),如果該語言無關的資源沒有定義,則ResourceManager得到的是Null 字元串。因為此時ResourceManager就不會把主程式集裡的資源當作最終Fallback的資源了。

解決問題的辦法

經過上面的分析,解決問題的辦法已經很清楚了,要麼再添加一個zh-Hans的資源檔,要麼顯式的使用NeutralResourcesLanguageAttribute通知ResourceManager,主程式集使用的資源語言是zh-Hans。

——Kevin Yang

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.