ABP文档 - 本地化

时间:2022-09-14 09:35:10

文档目录

本节内容:

简介

任何应用至少有一种用户界面语言,很多应用有多种,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文件,如下所示:

ABP文档 - 本地化

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文件,如下所示:

ABP文档 - 本地化

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资源文件里,我们可以为每个语言创建一个资源文件(右击项目,选择”添加项“,然后找到”资源文件“),如下所示:

ABP文档 - 本地化

MyTexts.resx包含默认的语言文本,MyTexts.tr.resx包含Turkish(土耳其)语言的文本,当我们打开MyTexts.resx文件,我们可以看到所有文本:

ABP文档 - 本地化

这种情况下,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="" 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文件:

ABP文档 - 本地化

默认(英文)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

ABP文档 - 本地化的更多相关文章

  1. ABP文档笔记系列

    ABP文档笔记 - 模块系统 及 配置中心 ABP文档笔记 - 事件BUS ABP文档笔记 - 数据过滤 ABP文档笔记 - 规约 ABP文档笔记 - 配置.设置.版本.功能.权限 ABP文档笔记 - ...

  2. ABP文档 - 通知系统

    文档目录 本节内容: 简介 发送模式 通知类型 通知数据 通知重要性 关于通知持久化 订阅通知 发布通知 用户通知管理器 实时通知 客户端 通知存储 通知定义 简介 通知用来告知用户系统里特定的事件发 ...

  3. ABP文档 - 导航

    文档目录 本节内容: 创建菜单 注册导航供应器 显示菜单 每个web应用都有一些菜单用来在页面/屏幕之间导航,ABP提供了一个通用的基础框架创建并显示菜单给用户. 创建菜单 一个应用可能由不同模块组成 ...

  4. ABP文档 - 异常处理

    文档目录 本节内容: 简介 启用错误处理 非AJAX请求 显示异常 UserFriendlyException Error 模型 AJAX 请求 异常事件 简介 这个文档针对Asp.net Mvc和W ...

  5. ABP文档 - Mvc 视图

    文档目录 本节内容: 简介 AbpWebViewPage 基类 简介 ABP通过nuget包Abp.Web.Mvc集成到Mvc视图里,你可以像往常那样创建常规的视图. AbpWebViewPage 基 ...

  6. ABP文档 - Mvc 控制器

    文档目录 本节内容: 简介 AbpController基类 本地化 其它 过滤 异常处理和结果包装 审计日志 验证 授权 工作单元 反伪造 模型绑定器 简介 ABP通过nuget包Abp.Web.Mv ...

  7. ABP文档 - Web Api 控制器

    文档目录 本节内容: 简介 AbpApiController 基类 本地化 其它 过滤 审计日志 授权 防伪造过滤 工作单元 结果包装和异常处理 结果缓存 验证 模块绑定器 简介 通过Abp.Web. ...

  8. ABP文档 :Overall - Introduction

    介绍 我们基于不同的需求创建不同的应用,但却在一次又一次地实现相同或相似的结构.至少在某种程度上,授权.验证.异常处理.日志.本地化.数据库连接管理.配置管理.审计日志属于通用的结构. 另外我们总是在 ...

  9. ABP文档 - Quartz 集成

    文档目录 本节内容: 简介 安装 创建工作 调度工作 更多 简介 Quartz 是一个功能完整的开源工作调度系统,可用于最小的应用到一个大型的企业系统.Abp.Quartz 包简单地把Quartz集成 ...

随机推荐

  1. EventBus vs Otto vs LiteEventBus

    http://blog.chengyunfeng.com/?p=449 http://litesuits.com/

  2. ADO&period;NET中使用事务进行数据库读写的办法

    使用事务一般是进行数据写入,数据读取一般是不需要这货的 第一种办法: 使用存储过程: 顾名思义,在存储过程中定义好变量,定义好事务开始,结束,错误回滚然后在ADO.NET中正常调用存储过程的方法就行 ...

  3. SwingConsole

    Java的Swing默认不是线程安全的,类的调度应该由线程分派器来安排.如果每个类都各个各的调度,有可能造成线程紊乱,带来一些难以检测的错误. 对于编写实验性代码(每次都只有一个JFrame),如果每 ...

  4. Webstorm入门-----常用快捷键

    为了提高敲代码的速度.我们所需要关注的各种快捷键: 首先,快捷键的设置                  相关连接: http://www.cnblogs.com/dc10101/archive/20 ...

  5. 汇编debug与masm命令

    汇编语言这块是我之前写在网易博客上的,不过那个账号基本已经作废了,所以现在抽个时间把当时的博客搬到CSDN上. 汇编命令(编译器masm命令):找到masm所在的文件夹,我的在d:\MASM中,用cm ...

  6. linux 安装MySql 5&period;7&period;21 操作步骤

    一:到mysql官网下载最新的mysql包 mysql-5.7.21-linux-glibc2.12-x86_64 https://dev.mysql.com/downloads/mysql/ 二:在 ...

  7. set nocount on&sol;off的作用,可配合存储过程使用

    当set nocount 为NO的时候,不返回计数(受Transact-SQL语句影响行数) 当set nocount 为OFF时,返回计数(默认返回) 当 SET NOCOUNT 为 ON 时,将不 ...

  8. Spring Websocket实现简易在线聊天功能

    针对Spring Websocket的实现,我参照了其他博主的文章https://www.cnblogs.com/leechenxiang/p/5306372.html 下面直接给出实现: 一.引入相 ...

  9. MySQL数据库(四)多表查询

    两张假设有两张表格A和B,把表格当作一个集合,那么表格中的记录就是集合中的一个元素. 两张表格如下: TableA:TableB: 2.1 内连接(只有一种场景) inner join 或者join( ...

  10. MySql联合查询

    将多条查询语句的结果合并为一个结果 *多表查询是横向连接,联合查询是纵向连接. 语法: 查询语句1 union 查询语句2 union 查询语句3 *union关键字默认去重,union all包含重 ...