Пустые строки в цепочке конфигурации переопределяют более ранних поставщиков конфигурации

Начиная с .NET 11, конфигурация, добавленная с помощью AddConfiguration, рассматривает пустую строку как существующее значение. Пустая строка поэтому переопределяет значения от поставщиков, зарегистрированных ранее во внешней конфигурации, вместо того, чтобы эти более ранние значения продолжали действовать.

Это изменение продолжает различие между пустыми и null значениями конфигурации, установленное в .NET 10 в статье сохранение значений NULL в конфигурации. Обработка null при цепочной конфигурации не изменяется.

Представленная версия

.NET 11 RC 1

Предыдущее поведение

ChainedConfigurationProvider.TryGet сообщил, что пустая строка не найдена. Следовательно, пустое значение в цепочке конфигурации не переопределяло значение, предоставленное предыдущим поставщиком:

using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;

IConfiguration inner = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>
    {
        ["Endpoint"] = "",
    })
    .Build();

IConfiguration configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>
    {
        ["Endpoint"] = "https://example.com",
    })
    .AddConfiguration(inner)
    .Build();

Console.WriteLine($"Endpoint: '{configuration["Endpoint"]}'");

До .NET 11 выходные данные были такими:

Endpoint: 'https://example.com'

Когда предыдущего значения не было, чтение ключа возвращало null, а раздел, единственным значением которого была цепочка пустой строки, считался несуществующим.

Новое поведение

Начиная с .NET 11, ChainedConfigurationProvider.TryGet сообщает, что пустая строка найдена. В приведенном выше примере пустое значение из inner переопределяет предыдущее значение, а выходные данные :

Endpoint: ''

Раздел, значение которого является пустой строкой, теперь считается существующим. Привязка также учитывает пустое значение вместо значения предыдущего поставщика. Например, привязка пустой строки поверх предыдущего числового значения к целочисленному свойству вызывает InvalidOperationException, последовательно с пустым значением, предоставленным непосредственно добавленным поставщиком.

null Значение в оболочке IConfiguration продолжает рассматриваться как отсутствующее, так как индексатор IConfiguration не может различать ключ, значение которого равно null, от отсутствующего ключа.

Тип разрушающего изменения

Это изменение поведения.

Причина изменения

Пустая строка является допустимым значением конфигурации. Рассмотрение этого как отсутствующего делало конфигурацию, объединённую в цепочку, несовместимой с поставщиками конфигурации, добавленными напрямую, и не позволяло приложениям намеренно очищать или отключать параметр, переопределяя его пустой строкой. Новое поведение сохраняет различие, проводимое поставщиком конфигурации, между пустым значением и отсутствующим значением. Дополнительные сведения см. в статье dotnet/runtime#131480.

Если пустая строка предназначена для переопределения более раннего значения, действие не требуется.

Если приложение полагается на пустую строку в цепочке конфигурации, позволяющей значению более раннего поставщика иметь приоритет, удалите этот ключ из цепочки конфигурации или представьте его как отсутствующий или null. Приложения, которые привязывают связанные значения к нестроковым типам, также должны проверять или нормализовать пустые значения перед привязкой, если пустое значение недопустимо для целевого типа. Для восстановления предыдущего поведения нет переключателя совместимости.

Затронутые API