Compartilhar via


O ConfigurationBinder ignora silenciosamente elementos de matriz inválidos

A partir do .NET 8, ConfigurationBinder ignora silenciosamente a matriz e os elementos de lista cujos valores não podem ser convertidos no tipo de destino. Anteriormente, os elementos com falha eram preservados como marcadores de posição null e a coleção resultante mantinha o mesmo comprimento do número de elementos na fonte de configuração.

Versão introduzida

.NET 8

Comportamento anterior

Anteriormente, ao associar uma matriz ou propriedade de lista por meio de Get<T>(IConfiguration) ou Bind(IConfiguration, Object), se o valor de um elemento não pudesse ser convertido no tipo de destino, esse elemento era preservado como um null espaço reservado no resultado. O comprimento da coleção correspondeu ao número de elementos na configuração.

// Configuration source, for example, appsettings.json:
// "Items": [
//   { "Name": "A", "Interval": 10 },
//   { "Name": "B", "Interval": "a" }   <-- invalid int
// ]

var settings = configuration.GetSection("Items").Get<MyItem[]>();

// .NET 6/7 result:
// settings.Length == 2
// settings[0] = { Name = "A", Interval = 10 }
// settings[1] = null   (conversion failed, placeholder preserved)

Novo comportamento

A partir do .NET 8, os elementos que falham na conversão de tipo são ignorados silenciosamente. A coleção resultante contém apenas elementos associados com êxito e tem um comprimento menor que o número de entradas na fonte de configuração.

var settings = configuration.GetSection("Items").Get<MyItem[]>();

// .NET 8+ result:
// settings.Length == 1
// settings[0] = { Name = "A", Interval = 10 }

Tipo de mudança disruptiva

Essa alteração é uma mudança comportamental.

Razão da alteração

A implementação interna de ConfigurationBinder foi refatorada no .NET 8. Em vez de pré-alocar a matriz de destino e associar os elementos in-situ (o que deixava null em caso de falha na conversão), o associador agora coleta apenas os elementos que foram associados com sucesso em uma lista temporária antes de compor a matriz final.

O comportamento anterior também era problemático para tipos de valor como int[]. Para um valor de configuração inválido, o vinculador armazenaria 0, que era indistinguível de um valor legítimo de 0. O novo comportamento evita essa ambiguidade.

  • Habilite ErrorOnUnknownConfiguration durante o desenvolvimento para exibir valores de configuração inválidos imediatamente em vez de remover elementos silenciosamente:

    var settings = configuration.GetSection("Items").Get<MyItem[]>(options =>
        options.ErrorOnUnknownConfiguration = true);
    

    A partir do .NET 8, essa opção também faz com que ConfigurationBinder lance um InvalidOperationException quando um valor não pode ser convertido ao tipo de destino. Para obter mais informações, consulte ConfigurationBinder lança uma exceção para valor incompatível.

  • Corrija valores de configuração inválidos. Verifique se todos os valores na fonte de configuração correspondem aos tipos esperados para o modelo associado.

  • Valide os comprimentos da coleção após a associação se o código depender do número de elementos correspondentes à fonte de configuração.

  • Use propriedades de strings com análise manual se precisar lidar graciosamente com valores que não podem ser convertidos e preservar todos os elementos do array.

APIs afetadas