.NET Core 2.1中无法使用SharedResources进行本地化

何塞·阿

我已经为这个问题战斗了好几个小时...而我找不到它...

我只是想本地化_Layout.cshtml文件。无论是IStringLocalizerIHtmlLocalizer似乎还没有找到资源文件。

我已关注并搜索:https : //github.com/MormonJesus69420/SharedResourcesExample .Net核心数据注释-共享资源的本地化 https://stackoverflow.com/search?q=shared+resources+.net+core https: //andrewlock.net/将本地化添加到asp-net-core-application /

我可能忽略了一些愚蠢的事情。

这是我的startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using EduPlaTools.Data;
using EduPlaTools.Models;
using EduPlaTools.Services;
using System.Globalization;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc.Razor;
using Pomelo.EntityFrameworkCore.MySql;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
using Microsoft.AspNetCore.HttpOverrides;

namespace EduPlaTools
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            // This is for string translation!
            // Adds Localization Services (StringLocalizer, HtmlLocalizer, etc.)
            // the opts.ResourcesPath = is the path in which the resources are found.
            // In our case the folder is named Resources!
            // There's specific and neutral resources.  (Specific en-US). (Neutral: es)
            /**
             * If no ResourcesPath is specified, the view's resources will be expected to be next to the views.
             * If ResourcesPath were set to "resources", then view resources would be expected to be ina  Resource directory,
             * in a path speicifc to their veiw (Resources/Views/Home/About.en.resx, for example).
             * 
             * */
            services.AddLocalization(opts => opts.ResourcesPath = "Resources");

            // services.AddBContext
            // There are subtle differences between the original and the modified version.

            services.AddDbContextPool<ApplicationDbContext>(options =>
                options.UseMySql(Configuration.GetConnectionString("MySQLConnection"),
                mysqlOptions =>
                {
                    mysqlOptions.ServerVersion(new Version(8, 0, 12), ServerType.MySql); // replace with your Server Version and Type
                }
                ));
                //options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            // Add application services.
            services.AddTransient<IEmailSender, EmailSender>();




            services.AddMvc()
                    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, options => options.ResourcesPath = "Resources")
                    .AddDataAnnotationsLocalization();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // This may be dangerous and is not recommended
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                    .CreateScope())
            {
                serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                     .Database.Migrate();
            }

            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }


            // These must line up with the ending of the .resx files.
            // Example: SharedResources.en.resx, SharedResources.es.rex

            // If you want to add specific, then do it like:
            // new CultureInfo("en-US")
            List<CultureInfo> supportedCultures = new List<CultureInfo>
            {
                new CultureInfo("es"),
                new CultureInfo("en"),
                new CultureInfo("es-ES"),
                new CultureInfo("en-US")
            };

            // Registers the localization, and changes the localization per request.
            app.UseRequestLocalization(new RequestLocalizationOptions
            {
                // We give the default support of Spanish.
                DefaultRequestCulture = new RequestCulture("es"),
                // Format numbers, dates, etc.
                SupportedCultures = supportedCultures,
                // The strings that we have localized
                SupportedUICultures = supportedCultures
            });

            // This will seed the databse:

            SeedDatabase.Initialize(app.ApplicationServices);

            app.UseStaticFiles();


            app.UseAuthentication();

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

这是我尝试在_Layout.cshtml中调用它的方式:

@using  Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@inject IHtmlLocalizer<SharedResources> _localizer;

@SharedLocalizer["Menu_Home"]

这是目录结构:

在此处输入图片说明

Here are the contents of SharedResources.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace EduPlaTools
{
    /**
     * This is a dummy class that is needed so Localization works.
     * Now in .NET Core Localization works as a service, and implementsw
     * naming conventions (AT the file level). Therefore, if the files do not
     * implement the correct name, there's going to be problems. 
     * 
     * See an example, here:
     * https://github.com/SteinTheRuler/ASP.NET-Core-Localization/blob/master/Resources/SharedResources.cs
     *
     * This is a workaround to create a Resource File that can be read by the entire
     * application. It's left in blank so the convention over configuration
     * picks it up.
     * 
     * */
    public class SharedResources
    {
    }
}

这是resx文件的内容:

在此处输入图片说明

在此处输入图片说明

我也尝试过重命名它们无济于事。(尝试过Resources.es.rex,Resources.rex)

我尝试设置断点以查看其行为。当然,找不到资源文件。然后,我回忆起一个不存在的密钥,将其与摩门教徒的回购进行了比较。我将其与我的输出进行了比较,但摩门教徒的回购协议未显示“ SearchedLocation”(它是在更高版本的.NET Core中引入的吗?)

摩门教回购: 在此处输入图片说明

我的回购: 在此处输入图片说明

我知道这可能很愚蠢……但是已经快四个小时了,因为我有很多事情要做,所以我无法停止!

有任何想法吗?

拉兹齐亚

if you want to implement localization with shared resource, you have to create your own culture localizer class:

public class CultureLocalizer
    {
        private readonly IStringLocalizer _localizer;
        public CultureLocalizer(IStringLocalizerFactory factory)
        {
            var type = typeof(ViewResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create("ViewResource", assemblyName.Name);
        }

        // if we have formatted string we can provide arguments         
        // e.g.: @Localizer.Text("Hello {0}", User.Name)
        public LocalizedString Text(string key, params string[] arguments)
        {
            return arguments == null
                ? _localizer[key]
                : _localizer[key, arguments];
        }
    }

then register it is startup:

services.AddSingleton<CultureLocalizer>();

and modify view locaization settings :

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddViewLocalization(o=>o.ResourcesPath = "Resources")

in your views you have to inject the culture localizer class before using it.

those are initial settings for view localization with shared resource, you need to configure localization settings for DataAnnotation, ModelBinding and Identity error messages as well.

these articles could help for starting:

Developing multicultural web application with ASP.NET Core 2.1 Razor Pages:

http://www.ziyad.info/en/articles/10-Developing_Multicultural_Web_Application

it includes step by step tutorial for localizing using shared resources, additionally, this article is about localizing Identity error messages :

http://ziyad.info/en/articles/20-Localizing_Identity_Error_Messages

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在SharedResources的帮助下进行ASP.NET Core本地化

ASP Net Core 2中的DataAnnotations本地化

能够使用多个po文件进行本地化asp.net core 2.2

通过_Layout.cshtml中的ASP.NET Core本地化在ASP.NET Core中进行翻译的问题

无法使用ASP.NET CORE 2.2生成用于本地化的Response cookie

使用VSCode的Asp.Net Core本地化无法正常工作

ASP.NET Core 3.0中的本地化

Asp.Net Core中的本地化

ASP.NET Core 2.2中的路由本地化

为什么.net core中的View本地化失败?

ASP.NET Core 2本地化(ViewLocalizer不起作用)

ASP.Net Core本地化

如何在Asp.Net Core中的Razor类库中使用本地化

使用Asp.Net Core获取控制器中的本地化显示属性

ASP.NET CORE(.NET Framework)和本地化

ASP.NET Core MVC (.NET 5) 中的本地化和全球化

本地化文件无法有效呈现MVC ASP.NET Core 2.2中的Razor页面

ASP .NET Core 2本地化会获取新语言的所有字符串

如何进行ASP.NET Core 3.1路由(Route,ActionName)本地化?

ASP.NET Core 3 MVC端点路由和按路由进行本地化

在单独的项目Asp.net Core MVC中进行本地化

.NET Core 2中的ReadAsMultipartAsync等价

.NET Core 2中缺少TaskCache类

在 OSX 上使用 MySQL 的 .NET Core 2

在ASP.net Core MVC 3.1中的HtmlHelper扩展方法中使用DataAnnotation本地化器

NET Core 3.1中如何在字符串本地化程序中正确使用资源文件?

ASP.NET CORE 2.0中的ASP.NET Core模型绑定错误消息本地化

ASP.NET Core DisplayAttribute本地化

在ASP.NET Core上本地化Enum条目