Локализация с SharedResources не работает в .NET Core 2.1 - PullRequest
0 голосов
/ 14 сентября 2018

Я боролся с этой проблемой часами ... и я не могу найти, что это ...

Я просто пытаюсь локализовать файл _Layout.cshtml. IStringLocalizer и IHtmlLocalizer не находят файлы ресурсов.

Я следил и искал: https://github.com/MormonJesus69420/SharedResourcesExample .NET Core Data Annotations - локализация с общими ресурсами https://stackoverflow.com/search?q=shared+resources+.net+core https://andrewlock.net/adding-localisation-to-an-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"]

Вот структура каталогов:

enter image description here

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:

enter image description here

enter image description here

Я также пытался переименовать их безрезультатно .. (Tried Resources.es.rex, Resources.rex)

Я попытался установить точки останова, чтобы посмотреть, как они себя ведут. Это, конечно, не нашел файлов ресурсов. Затем я сравнил его с репо Мормона , вспомнив несуществующий ключ. Я сравнил его с моим выводом, но в репозитории Мормона не отображается «SearchedLocation» (было ли оно представлено в более поздней версии .NET Core?)

Репо мормонов: enter image description here

Мой репо: enter image description here

Я знаю, что это может быть что-то глупое ... Но прошло уже около 4 часов, и я не могу остановиться, потому что у меня МНОГИЕ дела !!

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Я хотел добавить ответ, который развивает решение Laz. На всякий случай, если кто-то хочет иметь отдельные локализованные взгляды.

Назад в Startup.cs, у вас есть:

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

Технически, вы указываете MVC для поиска в папке «Ресурсы» в качестве основного пути, а затем следуйте соглашению для поиска локализованных файлов ресурсов.

Поэтому Если вы хотите локализовать представление Login.cshtml, найденное в Views/Account/Login.chsmtl, вам необходимо создать файл ресурсов в: Resources/Views/Account/Login.en.resx

Затем вам потребуется добавить следующее либо непосредственно в представление Login.cshtml, либо в _ViewImports.cshtml, чтобы сослаться на все виды:

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer

После этого в вашем коде вы можете сделать: Localizer["My_Resource_file_key"]

И вы переведете его. <Ч /> Вот несколько иллюстраций:

Folder Structure for the Individual Localization

Localized View

0 голосов
/ 14 сентября 2018

Если вы хотите реализовать локализацию с общим ресурсом, вы должны создать свой собственный класс локализатора культуры:

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];
        }
    }

, а затем зарегистрировать его при запуске:

services.AddSingleton<CultureLocalizer>();

и изменить представлениенастройки локализации:

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

в ваших представлениях вы должны внедрить класс локализатора культуры перед его использованием.

это начальные настройки для локализации представления с общим ресурсом, вам необходимо настроить параметры локализациидля сообщений об ошибках DataAnnotation, ModelBinding и Identity.

эти статьи могут помочь при запуске:

Разработка многокультурного веб-приложения с ASP.NET Core 2.1 Razor Pages:

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

включает пошаговое руководство по локализации с использованием общих ресурсов, кроме того, эта статья посвящена локализации сообщений об ошибках идентификации:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...