翼度科技»论坛 编程开发 .net 查看内容

Abp源码分析之Abp本地化

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
aspnetcore mvc 实现本地化

新建mvc项目


修改Program.cs
  1. using Microsoft.AspNetCore.Localization;
  2. using Microsoft.AspNetCore.Mvc.Razor;
  3. using System.Globalization;
  4. var builder = WebApplication.CreateBuilder(args);
  5. var supportedCultures = new[]
  6. {
  7.     new CultureInfo("zh-CN"),
  8.     new CultureInfo("en-US"),
  9. };
  10. builder.Services.Configure<RequestLocalizationOptions>(options =>
  11. {
  12.     options.DefaultRequestCulture = new RequestCulture("zh-CN");
  13.     options.SupportedCultures = supportedCultures;
  14.     options.SupportedUICultures = supportedCultures;
  15. });
  16. builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
  17. builder.Services.AddControllersWithViews()
  18.         .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
  19.         .AddDataAnnotationsLocalization();
  20. var app = builder.Build();
  21. app.UseRequestLocalization();
  22. if (!app.Environment.IsDevelopment())
  23. {
  24.     app.UseExceptionHandler("/Home/Error");
  25.     app.UseHsts();
  26. }
  27. app.UseHttpsRedirection();
  28. app.UseStaticFiles();
  29. app.UseRouting();
  30. app.UseAuthorization();
  31. app.MapControllerRoute(
  32.     name: "default",
  33.     pattern: "{controller=Home}/{action=Index}/{id?}");
  34. app.Run();
复制代码
跟本地化有关的代码
  1. var supportedCultures = new[]
  2. {
  3.     new CultureInfo("zh-CN"),
  4.     new CultureInfo("en-US"),
  5. };
  6. builder.Services.Configure<RequestLocalizationOptions>(options =>
  7. {
  8.     options.DefaultRequestCulture = new RequestCulture("zh-CN");
  9.     options.SupportedCultures = supportedCultures;
  10.     options.SupportedUICultures = supportedCultures;
  11. });
  12. builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
  13. builder.Services.AddControllersWithViews()
  14.         .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
  15.         .AddDataAnnotationsLocalization();
复制代码
  1. app.UseRequestLocalization();
复制代码
新建Resources目录,内容如下




修改Index.cshtml
  1. @using Microsoft.Extensions.Localization
  2. @using Microsoft.AspNetCore.Mvc.Localization
  3. @using WebApplication1.Controllers
  4. @inject IHtmlLocalizer<HomeController> HtmlLocalizer
  5. @inject IStringLocalizer<HomeController> StringLocalizer
  6. @inject IViewLocalizer ViewLocalizer
  7. @{
  8.     ViewData["Title"] = "Home Page";
  9. }
  10. string: @StringLocalizer["HelloWorld"]
  11. html: @HtmlLocalizer["HelloWorld"]
  12. view: @ViewLocalizer["HelloWorld"]
复制代码
访问首页



使用Json资源文件

新建mvc项目


安装WeihanLi.Extensions.Localization.Json包


我为了研究方便,下载了源码,所以引用了源码项目,我们正式使用时只要安装nuget包就可以了
修改Program.cs
  1. using System.Globalization;
  2. using Microsoft.AspNetCore.Localization;
  3. using Microsoft.AspNetCore.Mvc.Razor;
  4. using WeihanLi.Extensions.Localization.Json;
  5. var builder = WebApplication.CreateBuilder(args);
  6. var services = builder.Services;
  7. // Add services to the container.
  8. builder.Services.AddControllersWithViews();
  9. var supportedCultures = new[]
  10. {
  11.     new CultureInfo("zh-CN"),
  12.     new CultureInfo("en-US"),
  13. };
  14. services.Configure<RequestLocalizationOptions>(options =>
  15. {
  16.     options.DefaultRequestCulture = new RequestCulture("zh-CN");
  17.     options.SupportedCultures = supportedCultures;
  18.     options.SupportedUICultures = supportedCultures;
  19. });
  20. var resourcesPath = builder.Configuration.GetAppSetting("ResourcesPath") ?? "Resources";
  21. services.AddJsonLocalization(options =>
  22. {
  23.     options.ResourcesPath = resourcesPath;
  24.     // options.ResourcesPathType = ResourcesPathType.TypeBased;
  25.     options.ResourcesPathType = ResourcesPathType.CultureBased;
  26. });
  27. services.AddControllersWithViews()
  28.     .AddMvcLocalization(options =>
  29.     {
  30.         options.ResourcesPath = resourcesPath;
  31.     }, LanguageViewLocationExpanderFormat.Suffix);
  32. var app = builder.Build();
  33. app.UseRequestLocalization();
  34. // Configure the HTTP request pipeline.
  35. if (!app.Environment.IsDevelopment())
  36. {
  37.     app.UseExceptionHandler("/Home/Error");
  38.     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
  39.     app.UseHsts();
  40. }
  41. app.UseHttpsRedirection();
  42. app.UseStaticFiles();
  43. app.UseRouting();
  44. app.UseAuthorization();
  45. app.MapControllerRoute(
  46.     name: "default",
  47.     pattern: "{controller=Home}/{action=Index}/{id?}");
  48. app.Run();
复制代码
与aspnetcore原始的代码仅一下不同
  1. builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
  2. 改为:
  3. services.AddJsonLocalization(options =>
  4. {
  5.     options.ResourcesPath = resourcesPath;
  6.     // options.ResourcesPathType = ResourcesPathType.TypeBased;
  7.     options.ResourcesPathType = ResourcesPathType.CultureBased;
  8. });
复制代码
资源文件文件目录


内容:


源码分析


就是写了一个类JsonStringLocalizerFactory实现了IStringLocalizerFactory
写了JsonStringLocalizer实现了IStringLocalizer
在JsonStringLocalizer类的GetResources中加载json文件
  1.     private Dictionary<string, string> GetResources(string culture)
  2.     {
  3.         return _resourcesCache.GetOrAdd(culture, _ =>
  4.         {
  5.             var resourceFile = "json";
  6.             if (_resourcesPathType == ResourcesPathType.TypeBased)
  7.             {
  8.                 resourceFile = $"{culture}.json";
  9.                 if (_resourceName != null)
  10.                 {
  11.                     resourceFile = string.Join(".", _resourceName.Replace('.', Path.DirectorySeparatorChar), resourceFile);
  12.                 }
  13.             }
  14.             else
  15.             {
  16.                 resourceFile = string.Join(".",
  17.                     Path.Combine(culture, _resourceName.Replace('.', Path.DirectorySeparatorChar)), resourceFile);
  18.             }
  19.             _searchedLocation = Path.Combine(_resourcesPath, resourceFile);
  20.             Dictionary<string, string> value = null;
  21.             if (File.Exists(_searchedLocation))
  22.             {
  23.                 try
  24.                 {
  25.                     using var stream = File.OpenRead(_searchedLocation);
  26.                     value = JsonSerializer.Deserialize<Dictionary<string, string>>(stream);
  27.                 }
  28.                 catch (Exception e)
  29.                 {
  30.                     _logger.LogError(e, "Failed to get json content, path: {path}", _searchedLocation);
  31.                 }
  32.             }
  33.             else
  34.             {
  35.                 _logger.LogWarning("Resource file {path} not exists", _searchedLocation);
  36.             }
  37.             return value;
  38.         });
  39.     }
复制代码
ABP本地化

新建mvc项目 导入下面四个包


## 新建BookAppWebModule.cs
  1. using Volo.Abp.Localization.ExceptionHandling;
  2. using Volo.Abp.Localization;
  3. using Volo.Abp.Modularity;
  4. using Volo.Abp.VirtualFileSystem;
  5. using Volo.Abp.Autofac;
  6. using Volo.Abp.AspNetCore.Mvc;
  7. using Volo.Abp;
  8. using Volo.Abp.AspNetCore.Mvc.Localization;
  9. using Microsoft.AspNetCore.Mvc.Razor;
  10. using Microsoft.Extensions.Hosting.Internal;
  11. using BookApp.Localization;
  12. namespace BookApp
  13. {
  14.     [DependsOn(
  15.         typeof(AbpAutofacModule),
  16.         typeof(AbpLocalizationModule),
  17.         typeof(AbpVirtualFileSystemModule),
  18.         typeof(AbpAspNetCoreMvcModule)
  19.     )]
  20.     public class BookAppWebModule: AbpModule
  21.     {
  22.         public override void PreConfigureServices(ServiceConfigurationContext context)
  23.         {
  24.             var hostingEnvironment = context.Services.GetHostingEnvironment();
  25.             var configuration = context.Services.GetConfiguration();
  26.             context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
  27.             {
  28.                 options.AddAssemblyResource(
  29.                     typeof(BookStoreResource)
  30.                 );
  31.             });
  32.         }
  33.         public override void ConfigureServices(ServiceConfigurationContext context)
  34.         {
  35.             var hostingEnvironment = context.Services.GetHostingEnvironment();
  36.             ConfigureVirtualFileSystem(hostingEnvironment);
  37.             Configure<AbpLocalizationOptions>(options =>
  38.             {
  39.                 options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
  40.                 options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
  41.                 options.Languages.Add(new LanguageInfo("en", "en", "English"));
  42.                 options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
  43.                 options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
  44.                 options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
  45.                 options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
  46.                 options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi"));
  47.                 options.Languages.Add(new LanguageInfo("it", "it", "Italiano"));
  48.                 options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
  49.                 options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
  50.                 options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
  51.                 options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
  52.                 options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
  53.                 options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
  54.                 options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
  55.                 options.Languages.Add(new LanguageInfo("es", "es", "Español"));
  56.                 options.Resources
  57.                     .Add<BookStoreResource>("en")
  58.                     .AddVirtualJson("/Localization/BookStore");
  59.                 options.DefaultResourceType = typeof(BookStoreResource);
  60.             });
  61.             //context.Services.AddControllersWithViews()
  62.             //    .AddMvcLocalization(options =>
  63.             //    {
  64.             //        options.ResourcesPath = "/Localization/BookStore";
  65.             //    }, LanguageViewLocationExpanderFormat.Suffix);
  66.             //Configure<AbpExceptionLocalizationOptions>(options =>
  67.             //{
  68.             //    options.MapCodeNamespace("BookStore", typeof(BookStoreResource));
  69.             //});
  70.         }
  71.         public override void OnApplicationInitialization(ApplicationInitializationContext context)
  72.         {
  73.             var app = context.GetApplicationBuilder();
  74.             var env = context.GetEnvironment();
  75.             app.UseAbpRequestLocalization();
  76.             if (env.IsDevelopment())
  77.             {
  78.                 app.UseDeveloperExceptionPage();
  79.             }
  80.             app.UseHttpsRedirection();
  81.             app.UseStaticFiles();
  82.             app.UseRouting();
  83.         }
  84.         private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment)
  85.         {
  86.             Configure<AbpVirtualFileSystemOptions>(options =>
  87.             {
  88.                 options.FileSets.AddEmbedded<BookAppWebModule>();
  89.                 if (hostingEnvironment.IsDevelopment())
  90.                 {
  91.                     options.FileSets.ReplaceEmbeddedByPhysical<BookAppWebModule>(hostingEnvironment.ContentRootPath);
  92.                 }
  93.             });
  94.         }
  95.     }
  96. }
复制代码
修改Program.cs
  1. using BookApp;
  2. using Microsoft.Extensions.DependencyInjection;
  3. var builder = WebApplication.CreateBuilder(args);
  4. builder.Host
  5.     .AddAppSettingsSecretsJson()
  6.     .UseAutofac();
  7. await builder.AddApplicationAsync<BookAppWebModule>();
  8. var app = builder.Build();
  9. await app.InitializeApplicationAsync();
  10. app.MapControllerRoute(
  11.     name: "default",
  12.     pattern: "{controller=Home}/{action=Index}/{id?}");
  13. await app.RunAsync();
复制代码
新建资源文件与目录


en.json内容



我们只用到AppName
新建BookStoreResource.cs
  1. using Volo.Abp.Localization;
  2. namespace BookApp.Localization;
  3. [LocalizationResourceName("BookStore")]
  4. public class BookStoreResource
  5. {
  6. }
复制代码
修改Index.cshtml
  1. @using Microsoft.Extensions.Localization
  2. @using Microsoft.AspNetCore.Mvc.Localization
  3. @using BookApp.Controllers
  4. @using BookApp.Localization
  5. @inject IHtmlLocalizer<BookStoreResource> HtmlLocalizer
  6. @inject IStringLocalizer<BookStoreResource> StringLocalizer
  7. @inject IViewLocalizer ViewLocalizer
  8. @{
  9.     ViewData["Title"] = "Home Page";
  10. }
  11. string: @StringLocalizer["AppName"]
  12. html: @HtmlLocalizer["AppName"]
  13. view: @ViewLocalizer["AppName"]
复制代码
显示效果



源码分析

AbpLocalizationModule.cs中
  1. using Volo.Abp.Localization.Resources.AbpLocalization;
  2. using Volo.Abp.Modularity;
  3. using Volo.Abp.Settings;
  4. using Volo.Abp.Threading;
  5. using Volo.Abp.VirtualFileSystem;
  6. namespace Volo.Abp.Localization;
  7. [DependsOn(
  8.     typeof(AbpVirtualFileSystemModule),
  9.     typeof(AbpSettingsModule),
  10.     typeof(AbpLocalizationAbstractionsModule),
  11.     typeof(AbpThreadingModule)
  12.     )]
  13. public class AbpLocalizationModule : AbpModule
  14. {
  15.     public override void ConfigureServices(ServiceConfigurationContext context)
  16.     {
  17.         AbpStringLocalizerFactory.Replace(context.Services);
  18.         Configure<AbpVirtualFileSystemOptions>(options =>
  19.         {
  20.             options.FileSets.AddEmbedded<AbpLocalizationModule>("Volo.Abp", "Volo/Abp");
  21.         });
  22.         Configure<AbpLocalizationOptions>(options =>
  23.         {
  24.             options
  25.                 .Resources
  26.                 .Add<DefaultResource>("en");
  27.             options
  28.                 .Resources
  29.                 .Add<AbpLocalizationResource>("en")
  30.                 .AddVirtualJson("/Localization/Resources/AbpLocalization");
  31.         });
  32.     }
  33. }
复制代码
我们查看AbpStringLocalizerFactory.Replace(context.Services);的内容
  1.     internal static void Replace(IServiceCollection services)
  2.     {
  3.         services.Replace(ServiceDescriptor.Singleton<IStringLocalizerFactory, AbpStringLocalizerFactory>());
  4.         services.AddSingleton<ResourceManagerStringLocalizerFactory>();
  5.     }
复制代码
我们发现自定义的AbpStringLocalizerFactory实现了IStringLocalizerFactory
AbpDictionaryBasedStringLocalizer实现了IStringLocalizer

跟踪GetLocalizedString()

在这里读取json文件
相关文章

[理解ASP.NET Core - 全球化&本地化&多语言(Globalization and Localization) ](理解ASP.NET Core - 全球化&本地化&多语言(Globalization and Localization) - xiaoxiaotank - 博客园)
作者

吴晓阳(手机:13736969112微信同号)

来源:https://www.cnblogs.com/shiningrise/p/18541100
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具