2014年4月7日 星期一

C# 多國語系

C#的語系格式為languagecode2-country/regioncode2
可用以下列的語法列舉出所有語系

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    Console.WriteLine(ci.Name);
}

在.NET3.5之前簡中為zh-CHS,繁中為zh-CHT
在NET4.0之後簡中為zh-Hans,繁中為zh-Hant
在C#中影響目前語系的屬性有二個
Thread.CurrentThread.CurrentCulture影響的是控制台中的設定

例如日期、數字、貨幣的顯示格式

Thread.CurrentThread.CurrentUICulture影響的則是要選用那個語系的資源檔
在ASP.NET中可以透過設定檔來啟用多國語系

<system.web>
    <globalization culture="auto" uiCulture="auto" />
</system.web>

就會自動以Http通訊協定中的Accept-Language的順序來選擇語系

以ASP.NET WebForm為例,可以利用兩個特殊的資料夾
App_GlobalResources裡面的資源檔是全域的
App_LocalResources裡面的資源檔則是只有該層目錄下有效
將資源檔的名稱取成和Page一樣,就可以在頁面中使用GetLocalResourceObject取出資源檔中的值

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Object s1 = this.GetLocalResourceObject("s1");
            Response.Write(s1.ToString());
        }
    }
}

除了依瀏覽器的設定來選擇語系之外,也可以強制指定語系
比較常見的情況是讓使用者自行選擇語系後用cookie或session記住
然後在AcquireRequestState事件中取代目前的指定語系

namespace WebApplication1
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
        }

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            HttpCookie cookie = this.Request.Cookies["_lang"];
            if (cookie != null)
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
            }
        }
    }
}

在MVC專案中可以改用強型別的方式來存取資源檔
先新增一個Resources資料夾,然後建立各語系的資源檔

在View中直接使用該類別即可

如果資源檔要改存取資料庫的話,可以參考這個連結
http://afana.me/post/aspnet-mvc-internationalization-store-strings-in-database-or-xml.aspx