Null-värden bevarade i konfigurationen

.NET-konfigurationsbindningen hämtar konfigurationsvärden via konfigurationsproviders och försöker binda dessa värden till objektegenskaper. Tidigare, när ett konfigurationsvärde var null, behandlade bindemedlet det som om värdet inte fanns alls och hoppades därför över bindningen. Med andra ord skilde den inte mellan null värden och saknade värden. Det här beteendet orsakade betydande förvirring för användare som förväntade sig att explicit definierade null värden i konfigurationen skulle respekteras och bindas korrekt.

Dessutom konverterade JSON-konfigurationsprovidern null tidigare värden i konfigurationen till tomma strängar. Detta bidrog ytterligare till förvirring, eftersom egenskaper som är bundna till dessa värden skulle få en tom sträng i stället för den förväntade null.This further contributed to confusion, as properties bound to these values would receive an empty string rather than the expected null.

Den här ändringen åtgärdar båda problemen. JSON-konfigurationsprovidern rapporterar null nu värden korrekt utan att ändra dem, och binder behandlar null värden som giltiga indata och binder dem som andra värden.

Uppdateringen innehåller även förbättringar för att stödja bindningsvärden null i matriser och möjliggör bindning av tomma matriser.

Version lanserad

.NET 10

Tidigare beteende

Tidigare, när ett konfigurationsvärde var null, behandlade bindemedlet det som om värdet inte fanns alls och hoppade därför över bindningen. Systemet skilde inte mellan null värden och saknade värden.

Dessutom konverterade JSON-konfigurationsprovidern null värden i konfigurationen till tomma strängar. Detta gjorde att egenskaper som var bundna till dessa värden fick en tom sträng i stället för den förväntade null.

Överväg följande konfigurationsfilinnehåll appsettings.json :

{
    "NullConfiguration": {
        "StringProperty": null,
        "IntProperty": null,
        "Array1": [null, null],
        "Array2": []
    }
}

Och motsvarande bindningskod:

public class NullConfiguration
{
    public NullConfiguration()
    {
        // Initialize with non-default value to
        // ensure binding overrides these values.
        StringProperty = "Initial Value";
        IntProperty = 123;
    }
    public string? StringProperty { get; set; }
    public int? IntProperty { get; set; }
    public string[]? Array1 { get; set; }
    public string[]? Array2 { get; set; }
}

var configuration = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build().GetSection("NullConfiguration");

// Now bind the configuration.
NullConfiguration? result = configuration.Get<NullConfiguration>();

Console.WriteLine($"StringProperty: '{result!.StringProperty}', intProperty: {(result!.IntProperty.HasValue ? result!.IntProperty : "null")}");
Console.WriteLine($"Array1: {(result!.Array1 is null ?
    "null" : string.Join(", ", result!.Array1.Select(a => $"'{(a is null ? "null" : a)}'")))}");
Console.WriteLine($"Array2: {(result!.Array2 is null ?
    "null" : string.Join(", ", result!.Array2.Select(a => $"'{(a is null ? "null" : a)}'")))}");

Utdata:

StringProperty: '', intProperty: 123
Array1: '', ''
Array2: null

Förklaring av utdata:

  • StringProperty: Värdet null i JSON konverterades av JSON-providern till en tom sträng (""), vilket skrev över det ursprungliga värdet.
  • IntProperty: Förblev oförändrad (123) eftersom providern konverterade null till en tom sträng, som inte kunde parsas som ett int?, så det ursprungliga värdet behölls.
  • Array1: Bunden till en matris som innehåller två tomma strängar eftersom varje null matriselement behandlades som en tom sträng.
  • Array2: Kvarstod null eftersom en tom matris [] i JSON ignorerades av bindemedlet.

Nytt beteende

Från och med .NET 10 null är värdena nu korrekt bundna till motsvarande egenskaper, inklusive matriselement. Även tomma matriser identifieras korrekt och binds som tomma matriser i stället för att ignoreras.

Om du kör samma kodexempel får du följande resultat med hjälp av JSON-konfigurationsprovidern:

StringProperty: 'null', intProperty: null
Array1: 'null', 'null'
Array2:

Typ av brytande ändring

Det här är en beteendeförändring.

Orsak till ändring

Det tidigare beteendet var förvirrande och ledde ofta till användarklagomål. Genom att åtgärda det här problemet är konfigurationsbindningsprocessen nu mer intuitiv och konsekvent, vilket minskar förvirringen och anpassar beteendet till användarnas förväntningar.

Om du föredrar det tidigare beteendet kan du justera konfigurationen i enlighet med detta:

  • När du använder JSON-konfigurationsprovidern ersätter du null värden med tomma strängar ("") för att återställa det ursprungliga beteendet, där tomma strängar är bundna i stället för null.
  • För andra leverantörer som stöder null värden tar du bort posterna null från konfigurationen för att replikera det tidigare beteendet, där saknade värden ignoreras och befintliga egenskapsvärden förblir oförändrade.

Berörda API:er