博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DDD开发框架ABP之本地化/多语言支持
阅读量:4635 次
发布时间:2019-06-09

本文共 6297 字,大约阅读时间需要 20 分钟。

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

一、建立资源

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

XML文件

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

1 
2
3
4
5
6
7
8
9
Hi,10 Welcome to Simple Task System! This is a sample11 email content.
12
13

      上面代码中,文件开头的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键值对。

       

       .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资源文件在系统发布时,有两种存储方式,一种是文件系统,一种是嵌入到程序集。文件系统存储更灵活,它可以在系统运行中动态变更;嵌入到程序集的方式使用更方便,但编译后就不能更改。不同方式都需要在初始化是注册到配置中。

      文件系统方式注册时指定文件的地址目录:

1 Configuration.Localization.Sources.Add(2     new DictionaryBasedLocalizationSource(3         "ZeroSystem",4         new XmlFileLocalizationDictionaryProvider(5            HttpContext.Current.Server.MapPath("~/Localization/Zero")6         )7     )8 );

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

1 Configuration.Localization.Sources.Add(2      new DictionaryBasedLocalizationSource(3          "ZeroSystem",4          new XmlEmbeddedFileLocalizationDictionaryProvider(5              Assembly.GetExecutingAssembly(),6              "ZeroSystem.Web.Localization.Sources" )7     )8 );

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

注册RESX资源文件

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

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

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

三、使用资源

服务器端使用

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

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

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

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

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

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

L方法

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

1 public class HomeController : SimpleTaskSystemControllerBase2 {3     public ActionResult Index()4     {5         var helloWorldText = L("HelloWorld");6         return View();7     }8 }

Javascript端

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

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

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

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

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

多语言切换(基于AngularJS

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

1 angular.module('app').controller(controllerId, [2         '$scope', '$state', function ($scope, $state) {3             var vm = this;4             vm.languages = abp.localization.languages;5             vm.currentLanguage = abp.localization.currentLanguage;6       }7 ]);

      其中abp.localization.languages存储了语言的清单,abp.localization.currentLanguage存储了当前语言。

      然后在UI界面添加语言选项,以Razor+AngularJS为例,在header.cshtml文件中添加如下代码:

      ABP定义的语言对象包含了三个属性,分别是:

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

1 namespace Abp.Web.Mvc.Controllers.Localization 2 { 3     public class AbpLocalizationController : AbpController 4     { 5         [DisableAuditing] 6         public virtual ActionResult ChangeCulture(string cultureName, string returnUrl = "") 7         { 8             if (!GlobalizationHelper.IsValidCultureCode(cultureName)) 9             {10                 throw new AbpException("Unknown language: " + cultureName + ". It must be a valid culture!");11             }12 13             Response.Cookies.Add(new HttpCookie("Abp.Localization.CultureName", cultureName) { Expires = Clock.Now.AddYears(2) });14 15             if (Request.IsAjaxRequest())16             {17                 return Json(new MvcAjaxResponse(), JsonRequestBehavior.AllowGet);18             }19 20             if (!string.IsNullOrWhiteSpace(returnUrl))21             {22                 return Redirect(returnUrl);23             }24 25             return Redirect(Request.ApplicationPath);26         }27     }28 }

总结

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

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

转载于:https://www.cnblogs.com/defzhu/p/4844729.html

你可能感兴趣的文章
Redis 入门知识
查看>>
夏天过去了, 姥爷推荐几套来自smashingmagzine的超棒秋天主题壁纸
查看>>
转--Android如何在java代码中设置margin
查看>>
反射的所有api
查看>>
css 定位及遮罩层小技巧
查看>>
项目中非常有用并且常见的ES6语法
查看>>
[2017.02.23] Java8 函数式编程
查看>>
Knowledge Point 20180305 数据在计算机中的表示
查看>>
谈谈对web标准的理解
查看>>
58前端内推笔试2017(含答案)
查看>>
sprintf 和strcpy 的差别
查看>>
MPEG4与.mp4
查看>>
实验5
查看>>
git 下载 安装
查看>>
录制终端信息并回放
查看>>
JS中window.event事件使用详解
查看>>
ES6深入学习记录(一)class方法相关
查看>>
《BI项目笔记》用Excel2013连接和浏览OLAP多维数据集
查看>>
C语言对mysql数据库的操作
查看>>
SQL Server 数据库备份
查看>>