Microsoft.AspNetCore.Localization 自定义多语言获取

1 自定义 多语言加载 ,加载中间件

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddLocalization(options => options.ResourcesPath = "Resources");

            services.AddMvc()
                .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization();

            services.AddSingleton<IStringLocalizerFactory, CacheStringLocalizerFactory>();
            services.AddTransient<IStringLocalizer, CacheStringLocalizer>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            var supportedCultures = new[] { "en-US", "es-ES"};
            app.UseRequestLocalization(options =>
                options
                    .AddSupportedCultures(supportedCultures)
                    .AddSupportedUICultures(supportedCultures)
                    .SetDefaultCulture(supportedCultures[1])
            );

            app.UseStaticFiles();
            // To configure external authentication,
            // see: http://go.microsoft.com/fwlink/?LinkID=532715
            app.UseAuthentication();
            app.UseMvcWithDefaultRoute();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

2. IStringLocalizer

    public class CacheStringLocalizer : 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 CacheStringLocalizer(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()
        {
            try
            {
                return ReadFromCache();
            }
            catch (Exception)
            {
            }

            return new ConcurrentDictionary<string, string>();
        }

        private ConcurrentDictionary<string, string> ReadFromCache()
        {
            //TODO read from Cache
            ConcurrentDictionary<string, string> dic = new ConcurrentDictionary<string, string>();
            if (_baseResourceName.Contains("en-US"))
            {
                dic.TryAdd("Hello", "enUS-Cache");
                dic.TryAdd("FirstColumn", "FirstColumn");
                dic.TryAdd("SecondColumn", "SecondColumn");
                dic.TryAdd("ThirdColumn", "ThirdColumn");
                dic.TryAdd("One", "One");
                dic.TryAdd("Two", "Two");
                dic.TryAdd("Three", "Three");
            }
            if (_baseResourceName.Contains("es-ES"))
            {
                dic.TryAdd("Hello", "esES-Cache");
                dic.TryAdd("FirstColumn", "FirstColumn-esES");
                dic.TryAdd("SecondColumn", "SecondColumn-esES");
                dic.TryAdd("ThirdColumn", "ThirdColumn-esES");
                dic.TryAdd("One", "One-esES");
                dic.TryAdd("Two", "Two-esES");
                dic.TryAdd("Three", "Three-esES");
            }

            return dic;
        }
    }

3 IStringLocalizerFactory

    public class CacheStringLocalizerFactory : IStringLocalizerFactory
    {
        private readonly string _applicationName;
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly LocalizationOptions _options;
        public CacheStringLocalizerFactory(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 CacheStringLocalizer(_hostingEnvironment, _options, baseResourceName, null);
        }

        public IStringLocalizer Create(string baseName, string location)
        {
            location = location ?? _applicationName;

            string baseResourceName = baseName;
            baseResourceName = TrimPrefix(baseName, location + ".");

            return new CacheStringLocalizer(_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;
        }
    }

4  HomeController

 public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult SetLanguage(string culture, string returnUrl)
        {
            Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
                new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );

            return LocalRedirect(returnUrl);
        }
    }

5 view

@{
    ViewData["Title"] = "Home Page";
}

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@using System.Globalization

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems1 = LocOptions.Value.SupportedUICultures
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
    var supportedCultures = new[]
{
        new CultureInfo("en-US"),
        new CultureInfo("es-ES"),
     };
    var cultureItems = supportedCultures.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
    .ToList();

    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home"
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label>
        <select name="culture"
                onchange="this.form.submit();"
                asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"></select>
    </form>
    <label>Hello:</label>
    <label>@Localizer["Hello"]</label>
</div>
<div>
    <table>
        <thead>
            <tr>
                <th>@Localizer["FirstColumn"]</th>
                <th>@Localizer["SecondColumn"]</th>
                <th>@Localizer["ThirdColumn"]</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>@Localizer["One"]</td>
                <td>@Localizer["Two"]</td>
                <td>@Localizer["Three"]</td>
            </tr>
            <tr>
                <td>@Localizer["One"]</td>
                <td>@Localizer["Two"]</td>
                <td>@Localizer["Three"]</td>
            </tr>
            <tr>
                <td>@Localizer["One"]</td>
                <td>@Localizer["Two"]</td>
                <td>@Localizer["Three"]</td>
            </tr>
        </tbody>
    </table>
</div>

原文地址:https://www.cnblogs.com/gavinhuang/p/11996829.html

时间: 2024-10-08 22:22:58

Microsoft.AspNetCore.Localization 自定义多语言获取的相关文章

ASP.NET Core 源码阅读笔记(5) ---Microsoft.AspNetCore.Routing路由

这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项目地址. 路由功能是大家都很熟悉的功能,使用起来也十分简单,从使用的角度来说可讲的东西不多.不过阅读源码的过程的是个学习的过程,看看顶尖Coder怎么组织代码也是在提升自己. 我们知道现在ASP.NET Core中所有用到的功能都是服务,那么Routing服务是什么时候被添加到依赖注入容器的呢?答案是在StartUp类的ConfigureServices方法中

Microsoft.AspNetCore.Routing路由

Microsoft.AspNetCore.Routing路由 这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项目地址. 路由功能是大家都很熟悉的功能,使用起来也十分简单,从使用的角度来说可讲的东西不多.不过阅读源码的过程的是个学习的过程,看看顶尖Coder怎么组织代码也是在提升自己. 我们知道现在ASP.NET Core中所有用到的功能都是服务,那么Routing服务是什么时候被添加到依赖注入容器的呢?答案

Microsoft.AspNetCore.Authentication.Cookies从入门到精通 (二)

目录 Microsoft.AspNetCore.Authentication.Cookies从入门到精通 (二) Cookie加密 Cookie伪加密(序列化/反序列化) 减少Cookie中Value的大小 自定义Cookie管理功能 总结 未完待续...... Microsoft.AspNetCore.Authentication.Cookies从入门到精通 (二) ? 上篇文章我们介绍了Microsoft.AspNetCore.Authentication.Cookies的部分内容,由于篇幅

ASP.NET Core 源码阅读笔记(3) ---Microsoft.AspNetCore.Hosting

有关Hosting的基础知识 Hosting是一个非常重要,但又很难翻译成中文的概念.翻译成:寄宿,大概能勉强地传达它的意思.我们知道,有一些病毒离开了活体之后就会死亡,我们把那些活体称为病毒的宿主.把这种概念应用到托管程序上来,CLR不能单独存在,它必须依赖于某一个进程,我们把这种状况称之为:CLR必须寄宿于某一个进程中,而那个进程就是宿主. ASP.NET Core的一个大的改变就是就是将Web应用程序改成了自寄宿(当然在Windows上也还支持寄宿在IIS中).什么意思呢?我们知道,在之前

[转载]ASP.NET Core 源码阅读笔记(3) ---Microsoft.AspNetCore.Hosting

有关Hosting的基础知识 Hosting是一个非常重要,但又很难翻译成中文的概念.翻译成:寄宿,大概能勉强地传达它的意思.我们知道,有一些病毒离开了活体之后就会死亡,我们 把那些活体称为病毒的宿主.把这种概念应用到托管程序上来,CLR不能单独存在,它必须依赖于某一个进程,我们把这种状况称之为:CLR必须寄宿于某一个进程中,而那个进程就是宿主. ASP.NET Core的一个大的改变就是就是将Web应用程序改成了自寄宿. 什么意思呢?我们知道,在之前的ASP.NET版本中,ASP.NET的We

The &#39;Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer&#39; cannot serialize an object of type

原因:经过研究源码发现,目前Asp.Net Core MVC不支持复杂的数据类型 源码地址: Microsoft.AspNetCore.Mvc.ViewFeatures TempDataSerializer.cs CanSerializeType The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type 原文地址:https://www.cn

.NET Core 3.0或3.1 类库项目中引用 Microsoft.AspNetCore.App

在 ASP.NET Core 3.0+ web 项目中已经不需要在 .csproj 中添加对 Microsoft.AspNetCore.App 的引用<PackageReference Include="Microsoft.AspNetCore.App" />但是在 .NET Core 3.0+ 类库项目中如果不引用 Microsoft.AspNetCore.App ,就无法使用 ASP.NET Core 3.0 的程序集.在类库项目的 .csproj 中将 <Pro

Microsoft SQL Server 自定义函数整理大全

01.去除字符串中的html标记及标记中的内容 [叶子函数分享一]去除字符串中的html标记及标记中的内容 --1.创建函数 create function [dbo].[clearhtml] (@maco varchar(8000)) returns varchar(8000) as begin     declare @i int     while 1 = 1     begin        set @i=len(@maco)        set @maco=replace(@maco

Microsoft SQL Server 自定义函数整理大全(下)

34.字符串转成16进制函数 /**************************** 字符串转成16进制 作者:不得闲 QQ: 75492895 Email: [email protected] ****************************/ --创建函数(suiyunonghen(不得闲)) Create Function VarCharToHex(@Str Varchar(400)) returns varchar(800) as begin declare @i int,@