asp.net core 之多语言国际化自定义资源文件
先说说 asp.net core 默认的多语言和国际化。 官方文档
一:基本使用方法
先要安装 包 Microsoft.AspNetCore.Mvc.Localization (依赖 Microsoft.Extensions.Localization) 然后使用 资源文件保存不同的语言对应的数据。
1,在视图页面注入 IViewLocalizer ,然后在需要的地方使用即可。 比如:
@inject IViewLocalizer Localizer <h2>@Localizer["hello"]</h2>
其中 中括号中的字符 即是资源文件中的名称, 运行后,输出的即是 当前语言对应的资源文件下的设置的资源值。
那么有个问题来了,资源文件怎么设置?
1,默认情况下会去查找 设置的 LocalizationOptions.ResourcesPath 的值对应的文件夹,如果没有设置,则去根目录下查找。
在 Startup 中设置 ResourcesPath 。
services.AddLocalization(options => options.ResourcesPath = "Resources");
2,查找当前视图文件对应的同名资源文件。 默认支持 使用 点 . 和路径 path 查找两种方式,当然也可以指定其中一个方式。 比如 当前视图路径是 views/account/login.cshtml ,那么 查找的资源文件是 views/account/login.{CultureName}.resx 文件和 views.account.login.{CultureName}.resx 文件
services.AddMvc()
.AddViewLocalization()
//.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.SubFolder)
.AddDataAnnotationsLocalization();
3,如果是 model 类, 查找的路径则变成了model 类对应的命名空间即typeof(model).FullName 全路径。比如 ViewModels/account/login.{CultureName}.resx 文件和 ViewModels.account.login.{CultureName}.resx 文件 。同理 如果是在controller 那么,资源文件 则是 Controllers.HomeController.{CultureName}.resx 或者 Controllers/HomeController.{CultureName}.resx
二:解析
那么这个是如何实现的呢?如果我想使用 数据库或者是 json 文件来存在这些资源文件。
在试图文件中 注入的是 IViewLocalizer 接口,对应的实现是 ViewLocalizer 。ViewLocalizer 实现了IViewLocalizer 和IHtmlLocalizer 的定义,并且 IViewLocalizer 继承自IHtmlLocalizer。 ViewLocalizer 会注入一个IHtmlLocalizerFactory,然后 用 IHtmlLocalizerFactory创建一个 IHtmlLocalizer 对应的实例。 在创建的时候 会带入两个参数 ,一个是 当前 试图的路径,一个是当前应用名称。

IHtmlLocalizer 定义如下:

所以在 IHtmlLocalizer的实例中, 既可以轻松的获取对应的值。
因为 ViewLocalizer 会注入一个IHtmlLocalizerFactory 的实例。默认的实例 是 HtmlLocalizerFactory , 在 HtmlLocalizerFactory 的构造函数中会注入一个 IStringLocalizerFactory 的实例(位于Microsoft.Extensions.Localization.Abstractions)。
的定义是

而 IHtmlLocalizerFactory 的定义是

可以说 HtmlLocalizerFactory 是对 HtmlLocalizerFactory 的一个包装。
查阅代码知道 默认 IStringLocalizerFactory 实现是 ResourceManagerStringLocalizerFactory ,并且读取资源文件均是这个实现来操作。
回到开头的问题,假设我要使用 json 文件 代替 resx 文件。该如何实现呢,。? 有2种方法
1)只要实现对应的 IStringLocalizerFactory 并且代替默认的 ResourceManagerStringLocalizerFactory 。
2)重写 ResourceManagerStringLocalizerFactory 。
1) 1,定义一个 JsonStringLocalizerFactory 并实现 IStringLocalizerFactory 。
public class JsonStringLocalizerFactory : IStringLocalizerFactory
{
private readonly string _applicationName;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly LocalizationOptions _options;
public JsonStringLocalizerFactory(IHostingEnvironment hostingEnvironment, IOptions<LocalizationOptions> localizationOptions)
{
if (localizationOptions == null)
{
throw new ArgumentNullException(nameof(localizationOptions));
}
this._hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
this._options = localizationOptions.Value;
this._applicationName = hostingEnvironment.ApplicationName;
} public IStringLocalizer Create(Type resourceSource)
{
TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(resourceSource);
//Assembly assembly = typeInfo.Assembly;
//AssemblyName assemblyName = new AssemblyName(assembly.FullName); string baseResourceName = typeInfo.FullName;
baseResourceName = TrimPrefix(baseResourceName, _applicationName + "."); return new JsonStringLocalizer(_hostingEnvironment, _options, baseResourceName, null);
} public IStringLocalizer Create(string baseName, string location)
{
location = location ?? _applicationName; string baseResourceName = baseName;
baseResourceName = TrimPrefix(baseName, location + "."); return new JsonStringLocalizer(_hostingEnvironment, _options, baseResourceName, null);
} private static string TrimPrefix(string name, string prefix)
{
if (name.StartsWith(prefix, StringComparison.Ordinal))
{
return name.Substring(prefix.Length);
} return name;
}
}
2, JsonStringLocalizer
public class JsonStringLocalizer : IStringLocalizer
{
private readonly ConcurrentDictionary<string, string> _all; private readonly IHostingEnvironment _hostingEnvironment;
private readonly LocalizationOptions _options; private readonly string _baseResourceName;
private readonly CultureInfo _cultureInfo; public LocalizedString this[string name] => Get(name);
public LocalizedString this[string name, params object[] arguments] => Get(name, arguments); public JsonStringLocalizer(IHostingEnvironment hostingEnvironment, LocalizationOptions options, string baseResourceName, CultureInfo culture)
{
_options = options;
_hostingEnvironment = hostingEnvironment; _cultureInfo = culture ?? CultureInfo.CurrentUICulture;
_baseResourceName = baseResourceName + "." + _cultureInfo.Name;
_all = GetAll(); } public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
{
return _all.Select(t => new LocalizedString(t.Key, t.Value, true)).ToArray();
} public IStringLocalizer WithCulture(CultureInfo culture)
{
if (culture == null)
return this; CultureInfo.CurrentUICulture = culture;
CultureInfo.DefaultThreadCurrentCulture = culture; return new JsonStringLocalizer(_hostingEnvironment, _options, _baseResourceName, culture);
} private LocalizedString Get(string name, params object[] arguments)
{
if (_all.ContainsKey(name))
{
var current = _all[name];
return new LocalizedString(name, string.Format(_all[name], arguments));
}
return new LocalizedString(name, name, true);
} private ConcurrentDictionary<string, string> GetAll()
{
var file = Path.Combine(_hostingEnvironment.ContentRootPath, _baseResourceName + ".json");
if (!string.IsNullOrEmpty(_options.ResourcesPath))
file = Path.Combine(_hostingEnvironment.ContentRootPath, _options.ResourcesPath, _baseResourceName + ".json"); Debug.WriteLineIf(!File.Exists(file), "Path not found! " + file); if (!File.Exists(file))
return new ConcurrentDictionary<string, string>(); try
{
var txt = File.ReadAllText(file); return JsonConvert.DeserializeObject<ConcurrentDictionary<string, string>>(txt);
}
catch (Exception)
{
} return new ConcurrentDictionary<string, string>();
}
}
3,添加注入
services.AddSingleton<IStringLocalizerFactory, JsonStringLocalizerFactory>();
4,json 文件

上面的代码只是简单的实现了 使用 点(.) 作为分隔符的json 文件作为资源文件。(其实上面的代码运行后有个小问题)
代码已经放到 Github
2)。待实现~~~
链接:http://blog.wuliping.cn/post/aspnet-core-localization-and-custom-resource-service-with-file
asp.net core 之多语言国际化自定义资源文件的更多相关文章
- ASP.NET Core WebAPI实现本地化(单资源文件)
在Startup ConfigureServices 注册本地化所需要的服务AddLocalization和 Configure<RequestLocalizationOptions> p ...
- 让asp.net网站支持多语言,使用资源文件
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs&quo ...
- ASP.NET Core Web多语言项目
公司效益好了,准备和国外做生意,这个时候就需要多语言了. > 1. 这是一个ASP.NET Core Web多语言项目,主要展示项目的不同: > 2. 第一种:www.xxx.com/en ...
- Asp.Net Core 轻松学-一行代码搞定文件上传 JSONHelper
Asp.Net Core 轻松学-一行代码搞定文件上传 前言 在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建 ...
- [转]ASP.NET Core 开发-Logging 使用NLog 写日志文件
本文转自:http://www.cnblogs.com/Leo_wl/p/5561812.html ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 . ...
- ASP.NET Core 开发-Logging 使用NLog 写日志文件
ASP.NET Core 开发-Logging 使用NLog 写日志文件. NLog 可以适用于 .NET Core 和 ASP.NET Core . ASP.NET Core已经内置了日志支持,可以 ...
- 在ASP.NET Core中使用EPPlus导入出Excel文件
这篇文章说明了如何使用EPPlus在ASP.NET Core中导入和导出.xls/.xlsx文件(Excel).在考虑使用.NET处理excel时,我们总是寻找第三方库或组件.使用Open Offic ...
- struts2国际化---配置国际化全局资源文件并输出国际化资源信息
我们首先学习怎么配置国际化全局资源文件.并输出资源文件信息 1.首先struts2项目搭建完毕后,我们在src文件夹下.即struts2.xml同级文件夹下创建资源文件.资源文件的名称格式为: XXX ...
- Asp.Net Core 入门(三) —— 自定义中间件
上一篇我们讲了Startup文件,其中着重介绍了中间件,现在我们就来自定义我们自己的中间件吧. 中间件通常封装在一个类中,并使用扩展方法进行暴露.它需要拥有一个类型为RequestDelegate的成 ...
随机推荐
- Python List reverse()方法
reverse() 函数用于反向列表中元素,参数 NA,该方法没有返回值,但是会对列表的元素进行反向排序,原来的列表被改变,生成新的列表. 例子:list1 = ['Google', 'Runoob' ...
- UFLDL新版教程
http://ufldl.stanford.edu/tutorial/ 还带编程作业.
- Logstash详解之——input模块
原文地址 Logstash由三个组件构造成,分别是input.filter以及output.我们可以吧Logstash三个组件的工作流理解为:input收集数据,filter处理数据,output输出 ...
- dwd面试记录与最近面试的一些感想。
因为自己简历有些问题,额,面试官以为我有三年的工作经验. (吐槽一些智联的简历系统,)16年工作,一到18年自动变三年.这也忒坑人了. 工作年限一定要真实,避免出现问题,这会让面试官觉得你很不真诚. ...
- java继承。顾不了
总结:为什么结果显示所有数据都重复输出了呢? package com.sa; //java里的几个难以理解的概念.字节码文件.class文件.源文件 //.class文件指的是.编译后产生的字节码文件 ...
- linux设置支持中文
LANG="zh_CN.UTF-8" #LANG="zh_CN.GB18030" #LANG=en_US.UTF-8 LANGUAGE="zh_CN. ...
- catkin 工作空间
catkin 工作空间:组织和管理功能包的文件夹,以 catkin 工具编译 建立工作空间 sch01ar@ubuntu:~$ mkdir -p ~/catkin_ws/src sch01ar@ubu ...
- I/O完成端口(IOCP)
服务器: #include "stdafx.h" #include <winsock2.h> #pragma comment(lib, "ws2_32.lib ...
- OpenCV4Android 不需要安装OpenCVManager,就可以运行的方法
http://blog.csdn.net/yanzi1225627/article/details/27863615 OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种 ...
- Python 网络爬虫 002 (入门) 爬取一个网站之前,要了解的知识
网站站点的背景调研 1. 检查 robots.txt 网站都会定义robots.txt 文件,这个文件就是给 网络爬虫 来了解爬取该网站时存在哪些限制.当然了,这个限制仅仅只是一个建议,你可以遵守,也 ...