程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> <<ABP文檔>> 本地化,abp文檔本地化

<<ABP文檔>> 本地化,abp文檔本地化

編輯:關於.NET

<<ABP文檔>> 本地化,abp文檔本地化


 

文檔目錄

 

本節內容:

  • 簡介
  • 應用語言
  • 本地化源
    • XML文件
      • 注冊XML本地化源
    • JSOn文件
      • 注冊JSON本地化源
    • 資源文件
    • 自定義源
  • 獲取一個本地文本
    • 在服務端
      • 在MVc控制器裡
      • 在MVC視圖裡
    • 在Javascript裡
      • 格式化參數
      • 默認本地化源
  • 擴展本地化源
  • 獲取語言
  • 最佳實踐

 

簡介

任何應用至少有一種用戶界面語言,很多應用有多種,ABP為一個應用提供了一個靈活的本地化系統。

 

應用語言

第一件事就是聲明支持哪些語言,這在你的模塊的PreInitialize方法裡完成,如下所示:

Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true));
Configuration.Localization.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flag-tr"));

在服務端,你可以注入並使用ILocalizationManager,在客戶端,你可以使用javascript Api的abp.localization獲取所有可用語言列表和當前語言,famfamfam-flag-england (and tr)是一個CSS類,你可根據需要修改它,然後使用它在UI上顯示相關的標志。

ABP模板使用空上系統來顯示一個語言切換組合框給用戶,從模板創建並查看源碼可以了解更多。

 

本地化源

本地化文本可存儲於不同的源裡,甚至在同一個應用裡可以使用多個源(如果你有多個模塊,每個模塊可以定義一個獨立的本地化源,或一個模塊定義多個源),一個本地化源應當實現ILocalizationSource接口,然後它被注冊到ABP本地化配置裡。

每個本地化源必須有一個唯一的源名稱,如下列出預定義的源類型。

 

XML文件

本地化文本可以存儲在XML文件裡,XML文件內容類似於如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="en">
  <texts>
    <text name="TaskSystem" value="Task System" />
    <text name="TaskList" value="Task List" />
    <text name="NewTask" value="New Task" />
    <text name="Xtasks" value="{0} tasks" />
    <text name="CompletedTasks" value="Completed tasks" />
    <text name="EmailWelcomeMessage">Hi,
Welcome to Simple Task System! This is a sample
email content.</text>
  </texts>
</localizationDictionary>

XML文件必須包含編碼(utf-8),culture=”en“表明這個XML文件包含英文文本,文本的節點:name屬性用來標識一個文本,你可以使用value屬性或inner text(如最後一個)來設置本地化文本的值,我們為每個語言創建一個獨立的XML文件,如下所示:

 

SimpleTaskSystem是源名稱,SimpleTaskSystem.xml定義當前語言,當一個文本被請求,ABP從當前語言的XML文件裡獲取文本(使用Thread.CurrentThread查找當前語言),如果文本不存在,它將從默認語言的XML文件裡查找。

 

注冊XML本地化源

XML文件可存儲於文件系統裡或嵌入到一個程序集裡。

如果XML文件存儲於文件系統,我們可以用如下方式注冊一個XML本地化源:

Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        "SimpleTaskSystem",
        new XmlFileLocalizationDictionaryProvider(
            HttpContext.Current.Server.MapPath("~/Localization/SimpleTaskSystem")
            )
        )
    );

這在一個模塊的PreInitialize事件裡完成(更多信息查看模塊系統),ABP從指定文件夾裡找到所有XML文件並把它們注冊為本地化源。

如果XML嵌入到一個程序集裡,我們應當把所有本地化XML文件標記為嵌入的資源(選擇XML文件,打開屬性窗口(F4)並把生成操作改成嵌入的資源),然後我們可以用如下的方式注冊這個本地化源:

Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        "SimpleTaskSystem",
        new XmlEmbeddedFileLocalizationDictionaryProvider(
            Assembly.GetExecutingAssembly(),
            "MyCompany.MyProject.Localization.Sources"
            )
        )
    );

XmlEmbeddedFileLocalizationDictionaryProvider獲取一個程序集包含的xml文件(GetExecutingAssembly直接指向當前程序集) 和xml文件的命名空間(命名空間通過計算:程序集名稱+XML文件的目錄級次)。

注意:當給嵌入的XML文件添加後綴時,不要使用.號,如“MySource.tr.xml",應當用短橫,如”MySource-tr.xml“,因為當查找資源時.號會引起命名空間的問題。

 

JSON文件

JSON文件可以用來存儲一個本地化源的文本,下面是一個JSON本地化文件的示例:

{
  "culture": "en",
  "texts": {
    "TaskSystem": "Task system",
    "Xtasks": "{0} tasks"
  }
}

JSON文件應當編碼(utf-8),culture:“en“表明這個JSON文件包含英文文本,我們可以為每個語言創建單獨的JSON文件,如下所示:

MySourceName是源名稱,MySourceName.json定義了默認語言,這類似於XML文件。

 

注冊JSON本地化源

JSON文件可存儲在文件系統裡或是嵌入到一個程序集中。

如果存儲在文件系統裡,我們可以用以下方式注冊它:

Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        "MySourceName",
        new JsonFileLocalizationDictionaryProvider(
            HttpContext.Current.Server.MapPath("~/Localization/MySourceName")
            )
        )
    );

這在一個模塊的PreInitialize事件裡完成(更多信息查看模塊系統),ABP從指定文件夾裡找到所有JSON文件並把它們注冊為本地化源。

如果JSON嵌入到一個程序集裡,我們應當把所有本地化JSON文件標記為嵌入的資源(選擇JSON文件,打開屬性窗口(F4)並把生成操作改成嵌入的資源),然後我們可以用如下的方式注冊這個本地化源:

 Configuration.Localization.Sources.Add(
    new DictionaryBasedLocalizationSource(
        "MySourceName",
        new JsonEmbeddedFileLocalizationDictionaryProvider(
            Assembly.GetExecutingAssembly(),
            "MyCompany.MyProject.Localization.Sources"
            )
        )
    ); 

JsonEmbeddedFileLocalizationDictionaryProvider獲取一個程序集包含的JSON文件(GetExecutingAssembly直接指向當前程序集) 和JSON文件的命名空間(命名空間通過計算:程序集名稱+JSON文件的目錄級次)。

注意:當給嵌入的JSON文件添加後綴時,不要使用.號,如“MySource.tr.JSON",應當用短橫,如”MySource-tr.JSON“,因為當查找資源時.號會引起命名空間的問題。

 

資源文件

本地化文件同樣也能存儲於.net資源文件裡,我們可以為每個語言創建一個資源文件(右擊項目,選擇”添加項“,然後找到”資源文件“),如下所示:

MyTexts.resx包含默認的語言文本,MyTexts.tr.resx包含Turkish(土耳其)語言的文本,當我們打開MyTexts.resx文件,我們可以看到所有文本:

這種情況下,ABP使用.net內置的資源管理器來使用本地化,你應該把這個資源文件配置為一個本地化源:

Configuration.Localization.Sources.Add(
    new ResourceFileLocalizationSource(
        "MySource",
        MyTexts.ResourceManager
        ));

這個源的唯一名稱是MySource,MyTexts.ResourceManager是一個指向這個資源管理器的引用,將用它獲取本地化文本。這個配置在一個模塊的PreInitialize事件裡完成(更多信息查看模塊系統)。

 

自定義源

一個自定義的源可把文本存儲於不同的源,例如一個數據庫中,你可以直接實現ILocalizationSource接口或更簡單地繼承於DictionaryBasedLocalizationSource類(json和xml本地化源也使用這個)。  Module zero 就是在使用數據庫。

 

獲取一個本地文本

在創建一個源並把它注冊到ABP本地化系統後,就可以很簡單的本地化文本了。

 

在服務端

在服務端,我們可以注入ILocalizationManager並使用它的GetString方法:

var s1 = _localizationManager.GetString("SimpleTaskSystem", "NewTask");

GetString方法基於當前線程的UI文化從本地化源裡獲取字符串,如果沒有找到,它退回到默認語言。

如果都沒定義指定字符串,它默認返回人性化指定字符串並用[和]包裹它(而不拋出異常),例如:如果指定文本是“ThisIsMyText”,結果將是“[This is my text]”,這個行為可配置(可在你的模塊的PreInitialize裡使用Configuration.Localization)。

為不一直重復獲取源名稱,你可以先獲取源,然後從源裡獲取一個字符串:

var source = _localizationManager.GetSource("SimpleTaskSystem");
var s1 = source.GetString("NewTask"); 

這將用返回當前語言的文本,同時有幾個用來獲取不同語言和不同格式化參數的重載。

如果我們不能注入ILocalizationManager(可能在一個不能使用依賴注入的靜態上下文裡),我們可以簡單地使用LocalizationHelper靜態類,但只要有可能,還是注入並使用ILocalizationManager,因為LocalizationHelper是靜態的,不好為它寫單元測試。

如果你需要在一個應用服務、Mvc控制器、Razor視圖或繼承自AbpServiceBase的類裡進行本地化,可以快捷地使用L方法。

 

在Mvc控制器裡

在Mvc控制器和視圖裡通常需要本地化文本,這裡有一個快捷的方法,如下示例控制器所示:

public class HomeController : SimpleTaskSystemControllerBase
{
    public ActionResult Index()
    {
        var helloWorldText = L("HelloWorld");
        return View();
    }
}

用L方法本地化一個字符串,當然必須先提供一個源名稱,可以在如下所示的SimpleTaskSystemControllerBase裡提供: 

public abstract class SimpleTaskSystemControllerBase : AbpController
{
    protected SimpleTaskSystemControllerBase()
    {
        LocalizationSourceName = "SimpleTaskSystem";
    }
}

注意:它繼承自AbpController,因此你可以非常方便地使用L方法本地化文本。

 

在Mvc視圖裡

同樣,L方法也存在於視圖中:

<div>
    <form id="NewTaskForm" role="form">
        <div class="form-group">
            <label for="TaskDescription">@L("TaskDescription")</label>
            <textarea id="TaskDescription" data-bind="value: task.description" class="form-control" rows="3" placeholder="@L("EnterDescriptionHere")" required></textarea>
        </div>
        <div class="form-group">
            <label for="TaskAssignedPerson">@L("AssignTo")</label>
            <select id="TaskAssignedPerson" data-bind="options: people, optionsText: 'name', optionsValue: 'id', value: task.assignedPersonId, optionsCaption: '@L("SelectPerson")'" class="form-control"></select>
        </div>
        <button data-bind="click: saveTask" type="submit" class="btn btn-primary">@L("CreateTheTask")</button>
    </form>
</div>

為了能使用它,你應當讓你的視圖繼承自一個指定了源名稱的基類:

public abstract class SimpleTaskSystemWebViewPageBase : SimpleTaskSystemWebViewPageBase<dynamic>
{

}

public abstract class SimpleTaskSystemWebViewPageBase<TModel> : AbpWebViewPage<TModel>
{
    protected SimpleTaskSystemWebViewPageBase()
    {
        LocalizationSourceName = "SimpleTaskSystem";
    }
}

並在Web.config中配置這個視圖基類:

<pages pageBaseType="SimpleTaskSystem.Web.Views.SimpleTaskSystemWebViewPageBase"> 

如果你的解決方案是從ABP模板創建,那麼所有這些都已經完成。 

 

在javascript裡 

ABP使在javascript代碼裡本地化文本成為可能,首先,應該在頁面裡添加動態ABP腳本:

<script src="/AbpScripts/GetScripts" type="text/javascript"></script>

在客戶端裡,ABP會自動為本地化文本生成必要的javascript代碼,然後你就可以很容易地使用javascript獲取一個本地的文本,如下所示:

var s1 = abp.localization.localize('NewTask', 'SimpleTaskSystem');

NewTask是文本名稱,SimpleTaskSystem是源名稱,為不重復源名稱,你可以先得到源然後獲取文本:

var source = abp.localization.getSource('SimpleTaskSystem');
var s1 = source('NewTask');

 

格式化參數

Localization方法可以接受額外的格式化參數,例如:

abp.localization.localize('RoleDeleteWarningMessage', 'MySource', 'Admin');

//shortcut if source is got using getSource as shown above
source('RoleDeleteWarningMessage', 'Admin'); 

如果有“ RoleDeleteWarningMessage = 'Role {0} will be deleted'”,那麼本地化文本將會是“Role Admin will be deleted”。

 

默認本地化源

你可以設置一個默認的本地化源,然後使用abp.localization.localize方法,不用帶源名稱參數:

abp.localization.defaultSourceName = 'SimpleTaskSystem';
var s1 = abp.localization.localize('NewTask');

defaultSourceName是全局的並且一次只能是一個源名稱。

 

擴展本地化源

假設我們使用一個自身包含了本地化源的模塊,因為我們可能要改變它的本地化文本、添加新的文本或翻譯成另一種語言,所以ABP允許我們擴展一個本地化源,它目前能工作於XML和JSON文件(實質上,任何實現了IDictionaryBasedLocalizationSource接口的本地化源)。

ABP同樣定義了一些本地化源,例如,Abp.Web nuget包定義了名為“AbpWeb”本地化源,它是一個嵌入的XML文件:

默認(英文)XML文件,像下面所示(只顯示前兩個文本):

<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="en">
  <texts>
    <text name="InternalServerError" value="An internal error occurred during your request!" />
    <text name="ValidationError" value="Your request is not valid!" />
    ...
  </texts>
</localizationDictionary>

這擴展AbpWeb源,我們可以定義XML文件,假設我們只想修改InternalServerError文本,我們可以定義一下如下所示的XML文件:

<?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="en">
  <texts>
    <text name="InternalServerError" value="Sorry :( It seems there is a problem. Let us to solve it and please try again later." />
  </texts>
</localizationDictionary>

然後在我們模塊的PreInitialize方法裡注冊它:

Configuration.Localization.Sources.Extensions.Add(
    new LocalizationSourceExtensionInfo("AbpWeb",
        new XmlFileLocalizationDictionaryProvider(
            HttpContext.Current.Server.MapPath("~/Localization/AbpWebExtensions")
            )
        )
    );

如果想創建嵌入的XML資源文件(查看本地源小節),我們可以使用XmlEmbeddedFileLocalizationDictionaryProvider,ABP重寫(合並)基本地化源和我們的XML文件。我們也可以添加新的語言文件。

注意: 我們可以使用Json文件來擴展XML文件,反之亦然。

 

獲取語言

ILanguageManager用來獲取一個所有可用語言列表和當前語言。

 

最佳實踐

XML文件、JSON文件和資源文件有它們自身的優缺點,我們建議使用XML或JSON文件,不用資源文件,因為:

  • XML/JSon文件更容易編輯、擴展。
  • XML/JSon文件要求在獲取本地化文本時提供字符串鍵,而不像資源文件那樣需要編譯時的屬性,這也可以看成是一個缺點,但它卻可以在以後很容易的修改源,甚至可以移動本地化到一個數據庫而不用修改或寫本地化代碼(Module-Zero實現了它,並創建了一個基礎數據庫,為每個租戶提供本地化源,查看文檔)。

如果你使用XML或JSON,建議你不要把文本按名稱排序,要按創建時間排序,因為,當某人把它翻譯成另一種語言時,他可以很容易地看出哪一個是新添加的。

 

kid1412附:英文原文:http://www.aspnetboilerplate.com/Pages/Documents/Localization

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved