Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Mechanizm wiązania konfiguracji platformy .NET pobiera wartości za pośrednictwem dostawców konfiguracji i próbuje przypisać te wartości do właściwości obiektu. Wcześniej, gdy wartość konfiguracji była równa null, mechanizm powiązania traktował to tak, jakby ta wartość w ogóle nie istniała, i w związku z tym pomijał powiązanie. Innymi słowy, nie rozróżniała null wartości i brakujących wartości. To zachowanie spowodowało znaczną dezorientację użytkowników, którzy oczekiwali, że wartości null jawnie zdefiniowane w swojej konfiguracji będą respektowane i poprawnie wiązane.
Ponadto dostawca konfiguracji JSON wcześniej przekonwertował null wartości w konfiguracji na puste ciągi. Ponadto przyczyniło się to do zamieszania, ponieważ właściwości powiązane z tymi wartościami otrzymają pusty ciąg, a nie oczekiwaną wartość null.
Ta zmiana rozwiązuje oba problemy. Dostawca konfiguracji JSON teraz poprawnie zgłasza null wartości bez ich zmiany, a binder traktuje null wartości jako prawidłowe dane wejściowe, wiążąc je jak dowolną inną wartość.
Aktualizacja zawiera również ulepszenia w zakresie obsługi wiązania wartości null w obrębie tablic oraz umożliwia wiązanie pustych tablic.
Wersja wprowadzona
.NET 10
Poprzednie zachowanie
Wcześniej, gdy wartość konfiguracji miała wartość null, mechanizm wiązania traktował ją tak, jakby ta wartość w ogóle nie istniała, i w związku z tym pomijał wiązanie. System nie rozróżniał null wartości i brakujących wartości.
Ponadto dostawca konfiguracji JSON przekonwertował null wartości w konfiguracji na puste ciągi. Spowodowało to, że właściwości powiązane z tymi wartościami otrzymały pusty ciąg, a nie oczekiwaną nullwartość .
Rozważ następującą zawartość pliku appsettings.json konfiguracji:
{
"NullConfiguration": {
"StringProperty": null,
"IntProperty": null,
"Array1": [null, null],
"Array2": []
}
}
I odpowiadający mu kod wiązania:
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)}'")))}");
Wyjście:
StringProperty: '', intProperty: 123
Array1: '', ''
Array2: null
Wyjaśnienie danych wyjściowych:
-
StringPropertynull: Wartość w formacie JSON została przekonwertowana przez dostawcę JSON na pusty ciąg (""), zastępując wartość początkową. -
IntProperty: pozostał niezmieniony (123), ponieważ dostawca przekonwertowałnullna pusty ciąg, którego nie można przeanalizować jakoint?, więc oryginalna wartość została zachowana. -
Array1: Powiązana z tablicą zawierającą dwa puste ciągi, ponieważ każdynullelement tablicy był traktowany jako pusty ciąg. -
Array2: Pozostałnull, ponieważ pusta tablica[]w formacie JSON została zignorowana przez mechanizm wiązania.
Nowe zachowanie
Począwszy od platformy .NET 10, null wartości są teraz prawidłowo powiązane z odpowiednimi właściwościami, w tym elementami tablicy. Nawet puste tablice są poprawnie rozpoznawane i powiązane jako puste tablice, a nie ignorowane.
Uruchomienie tego samego przykładu kodu daje następujące wyniki przy użyciu dostawcy konfiguracji JSON:
StringProperty: 'null', intProperty: null
Array1: 'null', 'null'
Array2:
Typy wartościowe nieprzyjmujące wartości null
Mechanizm wiązania teraz również wiąże null z właściwościami typów wartości, które nie dopuszczają wartości null (na przykład int, bool lub typ wyliczeniowy), ustawiając je na domyślną wartość danego typu (default(T)).
Wcześniej przy użyciu dostawcy konfiguracji JSON powiązanie null elementu z taką właściwością zwróciło InvalidOperationException wartość podobną do następującej, ponieważ dostawca przekonwertował null element na pusty ciąg i nie można przekonwertować pustego ciągu na typ wartości docelowej:
Failed to convert configuration value at 'SomeSection:DayOfWeekProperty' to type 'System.DayOfWeek'.
Od wersji .NET 10 to samo wiązanie kończy się powodzeniem, a właściwość zostaje ustawiona na wartość domyślną. Na przykład null powiązane z właściwością DayOfWeek daje wynik DayOfWeek.Sunday (0), a null powiązane z właściwością int daje wynik 0. Nie jest zgłaszany żaden wyjątek.
Dostawcy, którzy przechowują rzeczywistą wartość null, tacy jak dostawca w pamięci, już przed platformą .NET 10 wiązali null z właściwościami typu wartości, które nie dopuszczają wartości null, przez ustawienie wartości domyślnej, a generator źródłowy konfiguracji również zachowuje się w ten sam sposób. Ta zmiana sprawia, że dostawca JSON i mechanizm wiązania oparty na refleksji są zgodne z tym zachowaniem.
Typ zmiany przełamującej
Jest to zmiana zachowania.
Przyczyna zmiany
Poprzednie zachowanie było mylące i często doprowadziło do skarg użytkowników. Dzięki rozwiązaniu tego problemu proces powiązania konfiguracji jest teraz bardziej intuicyjny i spójny, zmniejszając zamieszanie i dostosowując zachowanie do oczekiwań użytkownika.
Zalecana akcja
Jeśli wolisz poprzednie zachowanie, możesz odpowiednio dostosować konfigurację:
- W przypadku korzystania z dostawcy konfiguracji JSON zastąp
nullwartości pustymi ciągami (""), aby przywrócić oryginalne zachowanie, gdzie puste ciągi są powiązane zamiastnull. - W przypadku innych dostawców, którzy obsługują wartości
null, usuń z konfiguracji wpisynull, aby odtworzyć wcześniejsze działanie, w którym brakujące wartości są ignorowane, a istniejące wartości właściwości pozostają niezmienione. - Jeśli wcześniej zakładano, że w przypadku powiązania wartości
nullz właściwością typu wartości, która nie dopuszcza wartości null, zostanie zgłoszony wyjątek, należy pamiętać, że mechanizm powiązania teraz zamiast tego ustawia tę właściwość na jej wartość domyślną. Aby odróżnić brakującą wartość lub wartośćnullod rzeczywistej wartości, ustaw dla właściwości typ dopuszczający wartość null (na przykładint?lubDayOfWeek?) i po powiązaniu sprawdź, czy ma wartośćnull, albo jawnie zweryfikuj konfigurację.