Как получить строки файла.resx в ядре asp.net

Как получить строки resx в ядре asp.net? Я получаю строки, используя ResxResourceReader в mvc. Но я не могу получить то же самое в ядре asp.net.

Ответ 1

.NET Core изменил работу файлов ресурсов таким образом, что я чувствую себя неполным и запутанным (мне потребовались дни, чтобы понять), но это то, что вам нужно сделать:

  1. Добавьте следующий код в Startup.cs - Примечание. Измените языки, которые вы поддерживаете, и ResourcePath из "Ресурсов" будет только папкой, в которой хранятся файлы.resx позже.

        services.AddLocalization(o => o.ResourcesPath = "Resources");
        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("en-GB"),
                new CultureInfo("de-DE")
            };
            options.DefaultRequestCulture = new RequestCulture("en-US", "en-US");
    
            // You must explicitly state which cultures your application supports.
            // These are the cultures the app supports for formatting 
            // numbers, dates, etc.
    
            options.SupportedCultures = supportedCultures;
    
            // These are the cultures the app supports for UI strings, 
            // i.e. we have localized resources for.
    
            options.SupportedUICultures = supportedCultures;
        });
    
  2. Создайте папку в любом проекте, в котором вы хотите сохранить файлы resx по умолчанию, назовите его "Ресурсы".

  3. Создайте новый файл resx с определенной культурой и именем файла, который вы просмотрите позже: если у вас есть общий, вы можете сделать это: SharedResource.en-US.resx. Затем отключите генерацию автоматического кода, поскольку теперь это бесполезно.

  4. Создайте класс под названием "SharedResource" в том же месте, что и ваш файл resx. Он может быть пустым, он просто должен быть там, поэтому вы можете ссылаться на него позже.

  5. Где бы вы ни захотели использовать свой ресурс, IoC введет (в этом примере) IStringLocalizer <SharedResource> с именем "_localizer" или что-то в этом роде.

  6. Наконец, вы можете ссылаться на запись в файле ресурсов, выполнив _localizer ["My_Resource_Name"]

  7. Добавьте другой язык, создав новый файл resx с именем "SharedResource.de-DE.resx" или что-то еще в той же папке.

Папка "Ресурс" будет использоваться во всех сборках, чтобы просмотреть все их. Таким образом, эта папка может оказаться довольно захламленной, особенно если вы начнете получать информацию о конкретном материале здесь.

Я вижу, что разработчики пытались сделать здесь, но они отказались от слишком многого, чтобы добраться туда. Люди могут кодировать и добавлять переводческие материалы, фактически ничего не переводя. Они упростили работу разработчиков с самого начала, но в конечном итоге они стали более эффективными для разработчиков, которые фактически используют переводы. Теперь мы не можем автоматически генерировать что-либо. Мы должны IoC вводить ссылку на переводы для доступа к ним (не более статические, если вы не хотите использовать анти-шаблон ServiceLocater). Все имена являются жестко закодированными строками, поэтому теперь, если вы неправильно произнесете перевод, он просто вертет строку, которую вы ей дали, победив цель перевода в первую очередь, что означает, что вам, вероятно, понадобится обертка вокруг так что вы не полагаетесь на константы повсюду.

Я не могу поверить, что кто-то думал, что это хорошая идея, если честно. Почему бы не наклониться назад для разработчиков, которые не заботятся о переводах?

Я закончил создание обертки вокруг этого стиля. Единственная хорошая вещь в этом состоит в том, что если вы решите, что хотите получить ресурсы из базы данных, не потребуется никаких изменений кода, но теперь вам нужно добавить запись ресурса, добавить ее в интерфейс и затем реализовать ее для вытягивания он снова возвращается. Я использовал nameof(), поэтому мне не нужно было использовать константы, но это все еще хрупко, как если бы имя свойства или имя файла resx изменилось, оно сломает перевод без какого-либо сбоя - мне, вероятно, понадобится интеграционный тест чтобы я не получил то же значение, которое я отправляю:

public interface ICommonResource
{
    string ErrorUnexpectedNumberOfRowsSaved { get; }
    string ErrorNoRecordsSaved { get; }
    string ErrorConcurrency { get; }
    string ErrorGeneric { get; }

    string RuleAlreadyInUse { get; }
    string RuleDoesNotExist { get; }
    string RuleInvalid { get; }
    string RuleMaxLength { get; }
    string RuleRequired { get; }
}

public class CommonResource : ICommonResource
{
    private readonly IStringLocalizer<CommonResource> _localizer;

    public CommonResource(IStringLocalizer<CommonResource> localizer) =>
        _localizer = localizer;

    public string ErrorUnexpectedNumberOfRowsSaved => GetString(nameof(ErrorUnexpectedNumberOfRowsSaved));
    public string ErrorNoRecordsSaved => GetString(nameof(ErrorNoRecordsSaved));
    public string ErrorConcurrency => GetString(nameof(ErrorConcurrency));
    public string ErrorGeneric => GetString(nameof(ErrorGeneric));

    public string RuleAlreadyInUse => GetString(nameof(RuleAlreadyInUse));
    public string RuleDoesNotExist => GetString(nameof(RuleDoesNotExist));
    public string RuleInvalid => GetString(nameof(RuleInvalid));
    public string RuleMaxLength => GetString(nameof(RuleMaxLength));
    public string RuleRequired => GetString(nameof(RuleRequired));

    private string GetString(string name) =>
        _localizer[name];
}

Ответ 2

Старая версия пути (например, asp.net) заключается в создании файла ресурсов по умолчанию, такого как MyResources.resx и других файлов для разных культур MyResources.fr.resx,... и извлечения из него значений с помощью MyResources.MyValue1. Создание MyResources.resx создаст файл.cs со всеми вашими значениями ресурсов как статические свойства.

.Net Core рекомендует работать с IStringLocalizer<T> где T - это созданный вами класс, который совпадает с именем ваших файлов ресурсов. Вы можете начать разработку без какого-либо файла ресурсов и добавить их позже. Вам нужно ввести (локальный локатор локатора <MyResources>) на свой контроллер и получить значение с помощью _localizer ["MyValue1"];

Вы можете ознакомиться с официальной документацией основного ядра.net здесь