Partilhar via


O ConfigurationBinder ignora silenciosamente elementos de array inválidos

A partir do .NET 8, ConfigurationBinder ignora silenciosamente elementos de array e lista cujos valores não podem ser convertidos para o tipo de destino. Anteriormente, os elementos falhados eram preservados como null marcadores, 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 ligar uma propriedade de array ou lista via Get<T>(IConfiguration) ou Bind(IConfiguration, Object), se o valor de um elemento não pudesse ser convertido para o tipo alvo, esse elemento era preservado como null placeholder no resultado. O comprimento da coleção correspondia 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 tipos são ignorados silenciosamente. A coleção resultante contém apenas elementos encadernados com sucesso e tem um comprimento inferior ao 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

Esta alteração é de natureza comportamental .

Motivo da mudança

A implementação interna de ConfigurationBinder foi refatorada no .NET 8. Em vez de pré-alocar a matriz alvo e vincular os elementos no local (o que deixava null em caso de falha de conversão), o vinculador agora processa apenas os elementos vinculados com sucesso numa lista temporária antes de criar 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 binder armazenaria 0, que era indistinguível de um valor legítimo de 0. O novo comportamento evita esta ambiguidade.

  • Permita ErrorOnUnknownConfiguration durante o desenvolvimento que valores de configuração inválidos apareçam imediatamente, em vez de deixar elementos cair silenciosamente:

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

    A partir do .NET 8, esta opção também faz com que ConfigurationBinder lance um InvalidOperationException quando um valor não pode ser convertido para o tipo de destino. Para mais informações, veja ConfigurationBinder gera uma exceção para valores incompatíveis.

  • Corrigir valores de configuração inválidos. Assegure que todos os valores na sua fonte de configuração correspondem aos tipos esperados para o modelo bound.

  • Valida os comprimentos das coleções após a ligação se o teu código depender do número de elementos que correspondem à fonte da configuração.

  • Usa propriedades de string com análise manual se precisares de gerir valores não convertíveis de forma elegante e preservar todas as entradas do array.

APIs afetadas