DDD开发框架ABP之本地化/多语言支持

时间:2022-09-14 20:12:29

本地化(Localization)也就是多语言功能,借此用户能够选择他的母语或熟悉的语言来使用系统,这显然非常有利于软件系统推向国际化。一个应用程序的UI界面至少有一种语言,DDD开发框架ABP就提供了一个弹性的多语言框架,可以简化我们在多语言方面的开发时间。利用ABP完整实现多语言只需要简单地完成三个步骤:建立资源、配置资源以及使用资源。

一、建立资源

本地化的内容主要是文本字符串,ABP提供三种方式存储本地化资源的方式,分别是ASP.NET自带的资源文件、XML文件以及自定义的资源获取方式。ABP是分模块的,每个模块可以定义独立的本地化来源,每个本地化资源必须有一个唯一的名称。

XML文件
      以XML文件存储本地化资源时,XML文件必须是unicode(UTF-8),文件格式如下:

 <?xml version="1.0" encoding="utf-8" ?>
<localizationDictionary culture="en">
<texts>
<text name="ZeroSystem" value="Zero 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>

上面代码中,文件开头的culture="en"表明这个XML文件用于英语环境。text节点很简单地使用了name/value,name是一个代码,是唯一的,value是其在对应的语言下先是给用户的信息,可以是一个词,也可以是一段话。

我们应该为每种语言创建一个XML文件,比如:

ZeroSystem
ZeroSystem-zh-CN.xml
ZeroSytem-zh-TW.xml
ZeroSytem.xml

上面的文件列表中,Zero是资源的名称,没有带语言代码的XML文件用于默认语言。ABP会自动根据当前系统语言Thread.CurrentThread.CurrentUICulture从相应资源文件中获取文本信息,如果该语言没有,则自动从默认语言的XML文件中搜索。值得一提的是,在大系统中,我们可以考虑根据模块分类建立多个资源文件以方便管理,只需要建立多个不同名称的文件夹和一系列的资源文件即可。

RESX 资源文件

本地化信息也可以存储在.NET资源文件中,我们可以为每一种语言建立一个资源文件。.NET资源文件资源文件以.resx为后缀,也是name/value键值对。

DDD开发框架ABP之本地化/多语言支持

.NET资源文件中不带语言后缀的文件用于默认语言。其他方面与XML资源文件方式大同小异,本文不再做详细说明。

自定义资源

ABP的本地化框架除了支持XML外,也提供了自定义的资源,可以用其他方式来保存文本,比如数据库。我们可以直接实现ILocalization接口,或者从DictionaryBasedLocalizationSource类继承会更加容易些。下一篇将会讲述如何存储资源文件于数据库中。

二、配置资源

首先,我们需要声明系统支持哪几种语言。这可以在模块的PreInitialize事件中完成配置:

1 public override void PreInitialize()
2 {
3 Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "us.png", true));
4 Configuration.Localization.Languages.Add(new LanguageInfo("zh-TW", "繁體中文", "tw.png"));
5 Configuration.Localization.Languages.Add(new LanguageInfo("zh-CN", "简体中文", "cn.png"));
6 }

上面代码中,配置了三种语言,英语为默认语言。LanguageInfo参数包括代码,名称,图标和是否默认语言。

注册XML资源

XML资源文件在系统发布时,有两种存储方式,一种是文件系统,一种是嵌入到程序集。文件系统存储更灵活,它可以在系统运行中动态变更;嵌入到程序集的方式使用更方便,但编译后就不能更改。不同方式都需要在初始化是注册到配置中。
      文件系统方式注册时指定文件的地址目录:

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

预编译嵌入程序集的方式需要标记所有XML文件为“嵌入资源”(选择XML文件,打开属性窗口,修改“Build Action”为“Embedded Resource”)。注册代码如下:

 Configuration.Localization.Sources.Add(
new DictionaryBasedLocalizationSource(
"ZeroSystem",
new XmlEmbeddedFileLocalizationDictionaryProvider(
Assembly.GetExecutingAssembly(),
"ZeroSystem.Web.Localization.Sources" )
)
);

注意:预编译嵌入程序集的方式时,XML文件不要使用“.”作为分隔符,建议使用“-”,否则可能会出现找不到文件的问题。比如MySource.en.xml 改为 MySource-en.XML。

注册RESX资源文件

.NET资源文件在注册到配置时略有差异:

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

其中ZeroSystem是资源文件的唯一名称,MyTexts.ResourceManager是引用资源文件的命名空间。

三、使用资源

服务器端使用

在服务器端使用多语言,我们只需要注入ILocalizationManager接口,然后调用其GetString方法,第一个参数为资源来源的名称,第二个参数为资源字符串的名称。

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

GetString方法是基于当前线程的UI Culture设置从资源来源中取得字符串,如果没有找到,则从默认语言中取得字符串。

为了避免重复,可以先建立对象存储资源来源,后面调用GetString方法时只需要传递一个参数:

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

注意:如果我们在特定情况下(比如静态的上下文中)无法注入ILocalizationManager接口,我们也可以直接使用静态类LocalizationHelper。

L方法

  在应用服务层(Application Service)、MVC Controller,或者Razor View中,ABP还定义了一个更简单的方法L,来取得本地语言的字符串。

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

Javascript端

ABP同样支持的Javascript里面使用多语言。为了实现这个能力,我们首先需要引入Javascript文件:

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

ABP自动生成了取得本地化资源的Javascript方法,所以我们可以简单地取得本地化文本如下:

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

本地化文本同样可以带参数,比如“ Role {0} will be deleted”,通过下面的方法可以得到“Role Admin will be deleted”。

 var source = abp.localization.getSource('ZeroSystem');
source('RoleDeleteWarningMessage', 'Admin');

多语言切换(基于AngularJS

首先需要建立一个Angular控制器,比如在header.js文件中,注明语言变量:

 angular.module('app').controller(controllerId, [
'$scope', '$state', function ($scope, $state) {
var vm = this;
vm.languages = abp.localization.languages;
vm.currentLanguage = abp.localization.currentLanguage;
}
]);

其中abp.localization.languages存储了语言的清单,abp.localization.currentLanguage存储了当前语言。
      然后在UI界面添加语言选项,以Razor+AngularJS为例,在header.cshtml文件中添加如下代码:

 <li class="dropdown dropdown-language">
<a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle" data-hover="dropdown" data-close-others="true">
<img alt="" src="/assets/global/img/flags/{{vm.currentLanguage.icon}}.png" />
<span>{{vm.currentLanguage.displayName}}</span>
<i class="fa fa-angle-down"></i>
</a>
<ul class="dropdown-menu dropdown-menu-default">
<li ng-repeat="language in vm.languages" ng-hide="vm.currentLanguage.name == language.name">
<a href="~/AbpLocalization/ChangeCulture?cultureName={{language.name}}">
<img alt="" src="/assets/global/img/flags/{{language.icon}}.png" />
<span> {{language.displayName}}</span>
</a>
</li>
</ul>
</li>

ABP定义的语言对象包含了三个属性,分别是:
      name:语言名称,比如en, cn等
      displayName:显示的语言文本,比如:英语、日语、简体中文、繁体中文等。
      icon:显示的语言图标名称,ABP推荐的是国旗图标
      语言切换时,连接至ABP内置的一个MVC控制器,控制器的名称为:AbpLocalizationController,控制器定义了一个Action方法ChangeCulture。该控制器完整代码如下:

 namespace Abp.Web.Mvc.Controllers.Localization
{
public class AbpLocalizationController : AbpController
{
[DisableAuditing]
public virtual ActionResult ChangeCulture(string cultureName, string returnUrl = "")
{
if (!GlobalizationHelper.IsValidCultureCode(cultureName))
{
throw new AbpException("Unknown language: " + cultureName + ". It must be a valid culture!");
} Response.Cookies.Add(new HttpCookie("Abp.Localization.CultureName", cultureName) { Expires = Clock.Now.AddYears() }); if (Request.IsAjaxRequest())
{
return Json(new MvcAjaxResponse(), JsonRequestBehavior.AllowGet);
} if (!string.IsNullOrWhiteSpace(returnUrl))
{
return Redirect(returnUrl);
} return Redirect(Request.ApplicationPath);
}
}
}

总结

DDD开发框架ABP就提供了一个弹性的多语言框架,可以灵活的采用XML文件、.NET资源文件或数据库的方式存储多语言资源。ABP利用依赖注入提供了快捷的获取资源的方法,在前端Javascript也封装了支持多语言的方法。

具体如何实现在数据库中存储多语言资源,在下一篇博客《DDD开发框架ABP之本地化资源的数据库存储扩展》中有详细的实现过程和代码。当然通常说的多语言指的是软件系统的菜单、栏位、说明、帮助等开发阶段预先定义的内容,这些内容是由开发人员设定,在不同语言环境下不会因为用户的不同而存在差异。还有一种关键数据栏位的多语言,比如用户姓名、角色名称、供应商名称等,或许用户也希望系统能够具有多语言能力,ABP框架能否支持,该如何实现呢?

DDD开发框架ABP之本地化/多语言支持的更多相关文章

  1. DDD开发框架ABP之本地化资源的数据库存储扩展

    在上一篇<DDD开发框架ABP之本地化/多语言支持>中,我们知道,ABP开发框架中本地化资源存储可以采用XML文件,RESX资源文件,也提供了其他自定义的存储方式的扩展接口.ABP框架默认 ...

  2. Windows Phone 8本地化多语言支持

    原文 Windows Phone 8本地化多语言支持 在WP8平台处理本地化多语言的支持还是比较容易的,大部分工作都有VS IDE处理,开发者只需简单操作,并翻译本地资源即可实现. 无论您目前的应用是 ...

  3. Windows 8本地化多语言支持

    原文:Windows 8本地化多语言支持 在Win8平台处理本地化多语言的支持相对比较容易的,但比WP8稍微复杂一点,并不像WP8平台那样大部分工作都有VS IDE处理,Win8平台的操作基本需要开发 ...

  4. ios调用系统相册、相机 显示中文标题、本地化多语言支持

    因为调用系统相册.相机需要显示中文,所以搞了半天才知道是在Project->info->Custom ios Target Properties 添加 Localizations 并加入C ...

  5. DDD开发框架ABP之动态Web API层

    建立动态Web API 控制器 ASP.NET Boilerplate 能够自动为您的应用层产生Web API层.比如说我们有如下的一个应用服务: public interface ITaskAppS ...

  6. DDD开发框架ABP之导航菜单

    每一个网站都会有导航菜单(通常不止一个),ASP.NET Boilerplate(后文简称ABP)提供了一种创建和使用菜单的通用架构,利用架构我们可以方便的创建菜单并显示给用户.本文主要说明菜单的创建 ...

  7. ios本地化多语言支持

    右键 -> new file -> resources -> strings file 一定要命名为: Localizable.strings 点击这个文件 -> xocde ...

  8. 基于DDD的现代ASP&period;NET开发框架--ABP系列之2、ABP入门教程

    基于DDD的现代ASP.NET开发框架--ABP系列之2.ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boi ...

  9. DDD的ABP开发框架

    基于DDD的ABP开发框架初探   一.基本概念 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP是土耳其的以为架构师hikalkan开发 ...

随机推荐

  1. Javascript 中 with 的替代方案和String 中的正则方法

    这几天在升级自己的MVVM 框架,遇到很多小问题,就在这里统一解决了. with 语法 在代码中,要执行这么一个函数 function computeExpression(exp, scope) { ...

  2. xcode报错http

    问题: Xcode项目发送网络请求时,报错:“App Transport Security has blocked a cleartext HTTP (http://) resource load s ...

  3. &lbrack;PaPaPa&rsqb;&lbrack;需求说明书&rsqb;&lbrack;V1&period;0&rsqb;

    前   言 嘿嘿!嘿嘿!嘿嘿嘿嘿!大家好,我是XXX! 经过30K大大几篇文章在博客园怒刷存在感之后,咱们的小群瞬间从70人的数量增加到了将近400人.一下子加进来这么多人我还真是有点不适应啊! 我知 ...

  4. &lbrack;转&rsqb;Oracle分页之三:利用PagerView来实现无刷新GridView

    本文转自:http://www.cnblogs.com/scy251147/archive/2011/04/16/2018355.html 接上面一节,上面还存在问题就是分页控件使用的仍然是服务器端控 ...

  5. 继承进一步使用,以及super关键字

    目标: 1)掌握子类对象实例化过程 2)掌握方法覆盖概念和实现. 3)掌握super关键字的作用. 一,子类对象实例化过程 子类对象在实例化之前,必须先调用父类中的构造方法,再调用子类中的构造方法. ...

  6. Oracle EBS环境下查找数据源&lpar;OAF篇&rpar;

    在用户层设置预制文件:Personalize Self-Service Defn 的值为Yes 来启动个性化模式 参考:http://www.2cto.com/database/201109/1041 ...

  7. 二维码&lpar;2&rpar;二维码登录原理及Android客户端示例

    1,原理 服务器: 数据库: 建立一个2维码登录的数据表,产生一个登录页时,插入一条记录X,X含将要登录的用户名字段(初始为空),2维码中的数据字段(唯一) 登录页面: 在产生的2维码中包含关键数据Y ...

  8. Servlet&plus;Tomcat制作出第一个运行在Tomcat上的Java应用程序

    转载自:http://www.linuxidc.com/Linux/2011-08/41685.htm [日期:2011-08-27] 来源:csdn  作者:Cloudyxuq     1.IDE工 ...

  9. URAL 1303

    题目大意:给出N个区间[Li,Ri](1<=i<=N),一个正整数M,求N个区间里,并区间包含[0,M]的区间的最小个数(无解时输出:No solution). KB     64bit ...

  10. &lbrack;转&rsqb;linux权限补充:rwt rwT rws rwS 特殊权限

    众所周知,Linux的文件权限如: 777:666等,其实只要在相应的文件上加上UID的权限,就可以用到加权限人的身份去运行这个文件.所以我们只需要将bash复制出来到另一个地方,然后用root加上U ...