Можете ли вы предварительно просмотреть переопределения среды appsettings.json в ASP.NET Core?

В ASP.NET Core JsonConfigurationProvider загружает конфигурацию из appsettings.json, а затем считывает версию среды, appsettings.{Environment}.json, в зависимости от того, что IHostingEnvironment.EnvironmentName есть. Версия среды может переопределить значения базового файла appsettings.json.

Есть ли какой-либо разумный способ просмотреть, как будет выглядеть результирующая переопределенная конфигурация?

Очевидно, что вы можете написать модульные тесты, которые явно проверяют, переопределяются ли элементы в соответствии с вашими ожиданиями, но это будет очень трудоемкий обходной путь с обслуживанием каждый раз, когда вы меняете настройку. Это не очень хорошее решение, если вы просто хотите убедиться, что вы не ошиблись в скобках или неправильно написали имя элемента.

Вернувшись к преобразованиям web.config ASP.NET, вы можете просто щелкнуть правой кнопкой мыши преобразование в Visual Studio и выбрать «Предварительный просмотр преобразования». Существует также множество других способов предварительного просмотра XSLT-преобразования вне Visual Studio. Даже для параметризации web.config с помощью Parameters.xml вы можете по крайней мере выполнить Web Deploy и просмотреть полученный файл web.config, чтобы убедиться, что он получился правильным.

Кажется, нет встроенного способа предварительного просмотра эффектов appsettings.{Environment}.json в базовом файле в Visual Studio. Я не смог найти ничего за пределами VS, чтобы помочь с этим. Переопределение JSON кажется не таким уж распространенным явлением, хотя теперь оно является неотъемлемой частью ASP.NET Core.


person friggle    schedule 17.07.2019    source источник


Ответы (2)


Я понял, что вы можете выполнить предварительный просмотр с помощью функции слияния Json.NET после загрузки файлов настроек приложения в JObjects.

Вот простое консольное приложение, демонстрирующее это. Укажите ему путь к файлам настроек приложения, и он выдаст предварительный просмотр того, как они будут выглядеть в каждой среде.

    static void Main(string[] args)
    {
        string targetPath = @"C:\path\to\my\app";

        // Parse appsettings.json
        var baseConfig = ParseAppSettings($@"{targetPath}\appsettings.json");

        // Find all appsettings.{env}.json's
        var regex = new Regex(@"appsettings\..+\.json");
        var environmentConfigs = Directory.GetFiles(targetPath, "*.json")
            .Where(path => regex.IsMatch(path));

        foreach (var env in environmentConfigs)
        {
            // Parse appsettings.{env}.json
            var transform = ParseAppSettings(env);

            // Clone baseConfig since Merge is a void operation
            var result = (JObject)baseConfig.DeepClone();

            // Merge the two, making sure to overwrite arrays
            result.Merge(transform, new JsonMergeSettings
            {
                MergeArrayHandling = MergeArrayHandling.Replace
            });

            // Write the preview to file
            string dest = $@"{targetPath}\preview-{Path.GetFileName(env)}";
            File.WriteAllText(dest, result.ToString());
        }
    }

    private static JObject ParseAppSettings(string path)
        => JObject.Load(new JsonTextReader(new StreamReader(path)));

Хотя это не гарантирует, что какой-либо другой источник конфигурации не переопределит их после развертывания, это, по крайней мере, позволит вам убедиться, что взаимодействие между этими двумя файлами будет обрабатываться правильно.

person friggle    schedule 19.07.2019

На самом деле нет способа сделать это, но я думаю, что немного о том, как это на самом деле работает, поможет вам понять, почему.

С преобразованиями конфигурации произошла буквальная модификация файла, поэтому достаточно легко «предварительно просмотреть» это, показав результирующий файл. Система конфигурации в ASP.NET Core совершенно другая.

По сути, это просто словарь. Во время запуска каждый зарегистрированный поставщик конфигурации запускается в том порядке, в котором он был зарегистрирован. Поставщик считывает свой источник конфигурации, будь то файл JSON, системные переменные среды, аргументы командной строки и т. д., и создает пары ключ-значение, которые затем добавляются в основной «словарь» конфигурации. «Переопределение», такое как appsettings.{environment}.json, на самом деле просто еще один поставщик JSON, зарегистрированный после поставщика appsettings.json, который, очевидно, использует другой источник (файл JSON). Поскольку он регистрируется после того, как встречается существующий ключ, его значение перезаписывается, что характерно для всего, что добавляется в словарь.

Другими словами, «предварительный просмотр» будет завершенным объектом конфигурации (словарем), который состоит из ряда различных источников, а не только этих файлов JSON, и такие вещи, как переменные среды или аргументы командной строки, будут переопределять даже специфичный для среды JSON. (поскольку они зарегистрированы после этого), поэтому вы все равно технически не знаете, применяется ли JSON для конкретной среды или нет, потому что значение может исходить из другого источника, который отменяет это.

person Chris Pratt    schedule 17.07.2019
comment
Да, я понял. Хотя предварительный просмотр не может дать вам идеального представления о том, что в конечном итоге представляет собой ваша конфигурация, я все еще чувствую, что этой функции не хватает. Я признаю, что этот вопрос является прямой реакцией на одну неуместную скобку, которая заняла слишком много времени, чтобы определить ее как источник проблемы. - person friggle; 19.07.2019
comment
Я не думаю, что назвал бы это отсутствующей функцией. Я не вижу, чтобы это когда-либо добавлялось, и, честно говоря, не думаю, что это должно быть. То, о чем вы говорите, лучше обрабатывается простыми, хорошими методами разработки. Если вас беспокоят недопустимые файлы конфигурации JSON, вы можете запустить их через линтер как часть вашей сборки. Это не то, что ASP.NET Core нужно или даже должно обрабатывать за вас. - person Chris Pratt; 19.07.2019
comment
Оскорбительный JSON не был недействительным, но не соответствовал файлу, который он должен переопределить. Справится ли с этим линтер? - person friggle; 19.07.2019
comment
На самом деле нет, если только он не поддерживает пользовательские схемы, и вы приложили усилия для создания пользовательской схемы JSON. Лично я позволяю appsettings.json служить просто документацией, не предоставляя никаких реальных значений, если только они не являются полностью глобальными и применимы ко всем возможным средам. Все, что относится к среде, попадает в файл, специфичный для среды, а затем, если значение не указано по какой-либо причине, оно не будет просто возвращаться к значениям dev или чему-то еще. Скорее всего, вы получите исключение. Вы также можете добавить защитные предложения вокруг необходимых значений конфигурации перед их использованием. - person Chris Pratt; 19.07.2019