由于 API 的接口需要返回多语言, 因此参考了网上很多篇文章,, 有些文章写的太过于理论, 看起来比较费劲, 今天下午搞了一个下午, 总结了一下经验,,
做这个功能时, 主要参考了两篇文章:
大家可对照着看
一般有两种情况: 一种是 web 项目需要返回多语言,, 一种是 dll 里, 需要单独实现多语言的, 比如插件中
前提, 项目中需要引入 Microsoft.Extensions.Localization 包
一. Web 项目中
如果是默认创建的 ASP.NET core 的项目, 以及引用完 Microsoft.Extensions.Localization 包了, 所以不需要额外引入
1. 资源文件的位置问题
网上的教程中, 提到一个 SharedResource 的用法, 并且是放在 Resources 文件夹中, 今天试了很多次, 发觉是这么用的,
比如在不同的 area 中:
创建一个 Resources 文件夹,
然后添加一个叫 SharedResource 的类, 内容啥都不需要就要一个空的类而已
再添加对应语言的资源文件, 如: SharedResource.en.resx 或者 SharedResource.th.resx
结构:
- SharedResource.cs :
- namespace ZKXT.Devices.API.Areas.AppApi.Resources
- {
- public class SharedResource{}
- }
2.Start.cs 中:
- public void ConfigureServices(IServiceCollection services)
- {
- services.Configure<RequestLocalizationOptions>(options =>
- {
- options.DefaultRequestCulture = new RequestCulture("zn-cn"); // 默认的语言
- });
- services.AddLocalization(); // 注册相应 Service
- }
- public void Configure(IApplicationBuilder App, IWebHostEnvironment env)
- {
- var support = new List<CultureInfo>()
- {
- new CultureInfo("zh-cn"), // 注册多种语言, 具体可以查看 http://www.lingoes.net/zh/translator/langcode.htm 找对应
- new CultureInfo("en"),
- new CultureInfo("th")
- };
- App.UseRequestLocalization(x =>
- {
- x.SetDefaultCulture("zh-cn");
- x.SupportedCultures = support; // 设置支持的语言
- x.SupportedUICultures = support; // 设置 UI 语言, 这里有个很大的坑, 如果不设置该属性, 在 Action 中, CultureInfo.CurrentCulture 返回的是正确的语言, 但是在 CultureInfo.CurrentUICulture 返回的是默认语言
- x.AddInitialRequestCultureProvider(new AcceptLanguageHeaderRequestCultureProvider()); // 设置判断当前语言的方式, 我项目中是使用了 Accept-Language 的 header 值作为判断
- });
- }
2.Controller 中:
在构造函数中注入
public DevicesController(IStringLocalizer<SharedResource> localize=null):ControllerBase
注意: 这里的 SharedResource, 一定是要对应的 area 中的, 框架会根据 SharedResource 对应的 namespace 转换成对应的路径, 并读取相应的资源文件, 这个比较重要.
二. dll 中
1. 需手动引入 Microsoft.Extensions.Localization 包
2. 需要在 Web 项目中注入后, 在 request 中自动设定当前线程的语言
3. 资源文件目录结构如图:
- public class Base
- {
- private static IStringLocalizerFactory _factory = null;
- private string _name="";
- static Base()
- {
- _factory = new ResourceManagerStringLocalizerFactory(Options.Create(new LocalizationOptions(){ ResourcesPath = "Resources" }),
- NullLoggerFactory.Instance);
- _name=typeof(Base).Assembly.GetName().Name;
- }
- protected virtual IStringLocalizer GetLocalizer() // 后续使用该函数, 即可返回对应的 Localizer
- {
- return _factory.Create("SharedResource", _name); // 这里能指定名称, 就不是非要新建个 SharedResource 类了, 看了 factory 的源码, Create 的实现自带缓存功能, 所以不会每次都 new 一个类, 因此直接 Create 就好, 不需要自己做缓存
- }
- }
来源: https://www.cnblogs.com/kugar/p/12302100.html