Share via


Brongeneratie gebruiken in System.Text.Json

Brongeneratie System.Text.Json is beschikbaar in .NET 6 en nieuwere versies. Wanneer deze wordt gebruikt in een app, moet de taalversie van de app C# 9.0 of hoger zijn. In dit artikel wordt beschreven hoe u serialisatie met brongeneratie kunt gebruiken in uw apps.

Zie de modi voor het genereren van bronnen voor informatie over de verschillende modi voor het genereren van bronnen.

Standaardinstellingen voor het genereren van bronnen gebruiken

Brongeneratie gebruiken met alle standaardinstellingen (beide modi, standaardopties):

  1. Maak een gedeeltelijke klasse die is afgeleid van JsonSerializerContext.

  2. Geef het type op dat u wilt serialiseren of deserialiseren door deze toe te passen op JsonSerializableAttribute de contextklasse.

  3. Roep een methode aan JsonSerializer die:

Standaard worden beide brongeneratiemodi gebruikt als u er geen opgeeft. Zie De modus voor het genereren van bronnen later in dit artikel opgeven voor informatie over het opgeven van de modus die moet worden gebruikt.

Dit is het type dat wordt gebruikt in de volgende voorbeelden:

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

Dit is de contextklasse die is geconfigureerd om brongeneratie uit te voeren voor de voorgaande WeatherForecast klasse:

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
}

De typen WeatherForecast leden hoeven niet expliciet met kenmerken te worden opgegeven [JsonSerializable] . Leden die zijn gedeclareerd als object een uitzondering op deze regel. Het runtimetype voor een lid dat moet worden opgegeven object . Stel dat u de volgende klasse hebt:

public class WeatherForecast
{
    public object? Data { get; set; }
    public List<object>? DataList { get; set; }
}

En u weet dat het tijdens runtime mogelijk en int objecten heeftboolean:

WeatherForecast wf = new() { Data = true, DataList = new List<object> { true, 1 } };

int Vervolgens boolean moet deze worden gedeclareerd als[JsonSerializable]:

[JsonSerializable(typeof(WeatherForecast))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(int))]
public partial class WeatherForecastContext : JsonSerializerContext
{
}

Als u brongeneratie voor een verzameling wilt opgeven, gebruikt [JsonSerializable] u dit met het verzamelingstype. Voorbeeld: [JsonSerializable(typeof(List<WeatherForecast>))].

JsonSerializer methoden die gebruikmaken van brongeneratie

In de volgende voorbeelden biedt de statische Default eigenschap van het contexttype een exemplaar van het contexttype met standaardopties. Het contextexemplaren biedt een WeatherForecast eigenschap die een JsonTypeInfo<WeatherForecast> exemplaar retourneert. U kunt een andere naam voor deze eigenschap opgeven met behulp van de TypeInfoPropertyName eigenschap van het [JsonSerializable] kenmerk.

Voorbeelden van serialisatie

Met behulp van JsonTypeInfo<T>:

jsonString = JsonSerializer.Serialize(
    weatherForecast!, SourceGenerationContext.Default.WeatherForecast);

Met behulp van JsonSerializerContext:

jsonString = JsonSerializer.Serialize(
    weatherForecast, typeof(WeatherForecast), SourceGenerationContext.Default);

Met behulp van JsonSerializerOptions:

sourceGenOptions = new JsonSerializerOptions
{
    TypeInfoResolver = SourceGenerationContext.Default
};

jsonString = JsonSerializer.Serialize(
    weatherForecast, typeof(WeatherForecast), sourceGenOptions);

Voorbeelden van deserialisatie

Met behulp van JsonTypeInfo<T>:

weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
    jsonString, SourceGenerationContext.Default.WeatherForecast);

Met behulp van JsonSerializerContext:

weatherForecast = JsonSerializer.Deserialize(
    jsonString, typeof(WeatherForecast), SourceGenerationContext.Default)
    as WeatherForecast;

Met behulp van JsonSerializerOptions:

var sourceGenOptions = new JsonSerializerOptions
{
    TypeInfoResolver = SourceGenerationContext.Default
};
weatherForecast = JsonSerializer.Deserialize(
    jsonString, typeof(WeatherForecast), sourceGenOptions)
    as WeatherForecast;

Voorbeeld van het volledige programma

Hier volgen de voorgaande voorbeelden in een volledig programma:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace BothModesNoOptions
{
    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    [JsonSourceGenerationOptions(WriteIndented = true)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class SourceGenerationContext : JsonSerializerContext
    {
    }

    public class Program
    {
        public static void Main()
        {
            string jsonString = """
                {
                    "Date": "2019-08-01T00:00:00",
                    "TemperatureCelsius": 25,
                    "Summary": "Hot"
                }
                """;
            WeatherForecast? weatherForecast;

            weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
                jsonString, SourceGenerationContext.Default.WeatherForecast);
            Console.WriteLine($"Date={weatherForecast?.Date}");
            // output:
            //Date=8/1/2019 12:00:00 AM

            weatherForecast = JsonSerializer.Deserialize(
                jsonString, typeof(WeatherForecast), SourceGenerationContext.Default)
                as WeatherForecast;
            Console.WriteLine($"Date={weatherForecast?.Date}");
            // output:
            //Date=8/1/2019 12:00:00 AM

            var sourceGenOptions = new JsonSerializerOptions
            {
                TypeInfoResolver = SourceGenerationContext.Default
            };
            weatherForecast = JsonSerializer.Deserialize(
                jsonString, typeof(WeatherForecast), sourceGenOptions)
                as WeatherForecast;
            Console.WriteLine($"Date={weatherForecast?.Date}");
            // output:
            //Date=8/1/2019 12:00:00 AM

            jsonString = JsonSerializer.Serialize(
                weatherForecast!, SourceGenerationContext.Default.WeatherForecast);
            Console.WriteLine(jsonString);
            // output:
            //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}

            jsonString = JsonSerializer.Serialize(
                weatherForecast, typeof(WeatherForecast), SourceGenerationContext.Default);
            Console.WriteLine(jsonString);
            // output:
            //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}

            sourceGenOptions = new JsonSerializerOptions
            {
                TypeInfoResolver = SourceGenerationContext.Default
            };

            jsonString = JsonSerializer.Serialize(
                weatherForecast, typeof(WeatherForecast), sourceGenOptions);
            Console.WriteLine(jsonString);
            // output:
            //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}
        }
    }
}

Modus voor het genereren van bron opgeven

U kunt de modus op basis van metagegevens of serialisatieoptimalisatie opgeven voor een volledige context, die meerdere typen kan bevatten. U kunt ook de modus voor een afzonderlijk type opgeven. Als u beide doet, wordt de modusspecificatie voor een type wint.

Voorbeeld van serialisatie-optimalisatiemodus (snel pad)

  • Voor een volledige context:

    [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class SerializeOnlyContext : JsonSerializerContext
    {
    }
    
  • Voor een afzonderlijk type:

    [JsonSerializable(typeof(WeatherForecast), GenerationMode = JsonSourceGenerationMode.Serialization)]
    internal partial class SerializeOnlyWeatherForecastOnlyContext : JsonSerializerContext
    {
    }
    
  • Voorbeeld van het volledige programma

    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    namespace SerializeOnlyNoOptions
    {
        public class WeatherForecast
        {
            public DateTime Date { get; set; }
            public int TemperatureCelsius { get; set; }
            public string? Summary { get; set; }
        }
    
        [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
        [JsonSerializable(typeof(WeatherForecast))]
        internal partial class SerializeOnlyContext : JsonSerializerContext
        {
        }
        
        [JsonSerializable(typeof(WeatherForecast), GenerationMode = JsonSourceGenerationMode.Serialization)]
        internal partial class SerializeOnlyWeatherForecastOnlyContext : JsonSerializerContext
        {
        }
    
         public class Program
        {
            public static void Main()
            {
                string jsonString;
                WeatherForecast weatherForecast = new()
                    { Date = DateTime.Parse("2019-08-01"), TemperatureCelsius = 25, Summary = "Hot" };
    
                // Use context that selects Serialization mode only for WeatherForecast.
                jsonString = JsonSerializer.Serialize(weatherForecast,
                    SerializeOnlyWeatherForecastOnlyContext.Default.WeatherForecast);
                Console.WriteLine(jsonString);
                // output:
                //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}
    
                // Use a context that selects Serialization mode.
                jsonString = JsonSerializer.Serialize(weatherForecast,
                    SerializeOnlyContext.Default.WeatherForecast);
                Console.WriteLine(jsonString);
                // output:
                //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}
            }
        }
    }
    

Voorbeeld van op metagegevens gebaseerde modus

  • Voor een volledige context:

    [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class MetadataOnlyContext : JsonSerializerContext
    {
    }
    
    jsonString = JsonSerializer.Serialize(
        weatherForecast!, MetadataOnlyContext.Default.WeatherForecast);
    
    weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
        jsonString, MetadataOnlyContext.Default.WeatherForecast);
    
  • Voor een afzonderlijk type:

    [JsonSerializable(typeof(WeatherForecast), GenerationMode = JsonSourceGenerationMode.Metadata)]
    internal partial class MetadataOnlyWeatherForecastOnlyContext : JsonSerializerContext
    {
    }
    
    jsonString = JsonSerializer.Serialize(
        weatherForecast!,
        MetadataOnlyWeatherForecastOnlyContext.Default.WeatherForecast);
    
    weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
        jsonString, MetadataOnlyWeatherForecastOnlyContext.Default.WeatherForecast);
    
  • Voorbeeld van het volledige programma

    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    namespace MetadataOnlyNoOptions
    {
        public class WeatherForecast
        {
            public DateTime Date { get; set; }
            public int TemperatureCelsius { get; set; }
            public string? Summary { get; set; }
        }
    
        [JsonSerializable(typeof(WeatherForecast), GenerationMode = JsonSourceGenerationMode.Metadata)]
        internal partial class MetadataOnlyWeatherForecastOnlyContext : JsonSerializerContext
        {
        }
    
        [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Metadata)]
        [JsonSerializable(typeof(WeatherForecast))]
        internal partial class MetadataOnlyContext : JsonSerializerContext
        {
        }
    
        public class Program
        {
            public static void Main()
            {
                string jsonString = """
                    {
                      "Date": "2019-08-01T00:00:00",
                      "TemperatureCelsius": 25,
                      "Summary": "Hot"
                    }
                    """;
                WeatherForecast? weatherForecast;
    
                // Deserialize with context that selects metadata mode only for WeatherForecast only.
                weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
                    jsonString, MetadataOnlyWeatherForecastOnlyContext.Default.WeatherForecast);
                Console.WriteLine($"Date={weatherForecast?.Date}");
                // output:
                //Date=8/1/2019 12:00:00 AM
    
                // Serialize with context that selects metadata mode only for WeatherForecast only.
                jsonString = JsonSerializer.Serialize(
                    weatherForecast!,
                    MetadataOnlyWeatherForecastOnlyContext.Default.WeatherForecast);
                Console.WriteLine(jsonString);
                // output:
                //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":"Hot"}
    
                // Deserialize with context that selects metadata mode only.
                weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
                    jsonString, MetadataOnlyContext.Default.WeatherForecast);
                Console.WriteLine($"Date={weatherForecast?.Date}");
                // output:
                //Date=8/1/2019 12:00:00 AM
    
                // Serialize with context that selects metadata mode only.
                jsonString = JsonSerializer.Serialize(
                    weatherForecast!, MetadataOnlyContext.Default.WeatherForecast);
                Console.WriteLine(jsonString);
                // output:
                //{"Date":"2019-08-01T00:00:00","TemperatureCelsius":0,"Summary":"Hot"}
            }
        }
    }
    

Ondersteuning voor brongeneratie in ASP.NET Core

Gebruik in Blazor-apps overbelastingen van en HttpClientJsonExtensions.PostAsJsonAsync uitbreidingsmethoden die een context voor het genereren van HttpClientJsonExtensions.GetFromJsonAsync bronnen gebruiken of TypeInfo<TValue>.

Vanaf .NET 8 kunt u ook overbelastingen van extensiemethoden gebruiken die een context voor het genereren van HttpClientJsonExtensions.GetFromJsonAsAsyncEnumerable bronnen accepteren of TypeInfo<TValue>.

Gebruik in Razor Pages-, MVC-, SignalR- en Web-API-apps de JsonSerializerOptions.TypeInfoResolver eigenschap om de context op te geven.

[JsonSerializable(typeof(WeatherForecast[]))]
internal partial class MyJsonContext : JsonSerializerContext { }
var serializerOptions = new JsonSerializerOptions
{
    TypeInfoResolver = MyJsonContext.Default
};

services.AddControllers().AddJsonOptions(
    static options =>
        options.JsonSerializerOptions.TypeInfoResolverChain.Add(MyJsonContext.Default));

Gebruik in Razor Pages-, MVC-, SignalR- en Web-API-apps de JsonSerializerOptions.TypeInfoResolver eigenschap om de context op te geven.

[JsonSerializable(typeof(WeatherForecast[]))]
internal partial class MyJsonContext : JsonSerializerContext { }
var serializerOptions = new JsonSerializerOptions
{
    TypeInfoResolver = MyJsonContext.Default
};

services.AddControllers().AddJsonOptions(
    static options =>
        options.JsonSerializerOptions = serializerOptions);

Gebruik in Razor Pages-, MVC-, SignalR- en Web-API-apps de AddContext methode van JsonSerializerOptions, zoals wordt weergegeven in het volgende voorbeeld:

[JsonSerializable(typeof(WeatherForecast[]))]
internal partial class MyJsonContext : JsonSerializerContext { }
services.AddControllers().AddJsonOptions(options =>
    options.JsonSerializerOptions.AddContext<MyJsonContext>());

Notitie

JsonSourceGenerationMode.Serializationserialisatie van snelpaden wordt niet ondersteund voor asynchrone serialisatie.

In .NET 7 en eerdere versies is deze beperking ook van toepassing op synchrone overbelastingen van JsonSerializer.Serialize die accepteren een Stream. Vanaf .NET 8, hoewel streamingserialisatie modellen op basis van metagegevens vereist, valt het terug op snel pad als de nettoladingen klein genoeg zijn om in de vooraf vastgestelde buffergrootte te passen. Zie https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/#json voor meer informatie.

Standaardinstellingen voor weerspiegeling uitschakelen

Omdat System.Text.Json weerspiegeling standaard wordt gebruikt, kan het aanroepen van een eenvoudige serialisatiemethode systeemeigen AOT-apps verbreken, die niet alle vereiste reflectie-API's ondersteunen. Deze onderbrekingen kunnen lastig zijn om te diagnosticeren, omdat ze onvoorspelbaar kunnen zijn, en apps worden vaak opgespoord met behulp van de CoreCLR-runtime, waar weerspiegeling werkt. Als u in plaats daarvan serialisatie op basis van weerspiegeling expliciet uitschakelt, kunt u eenvoudiger een diagnose stellen. Code die gebruikmaakt van serialisatie op basis van weerspiegeling, zorgt ervoor dat een InvalidOperationException beschrijvend bericht tijdens runtime wordt gegenereerd.

Als u standaardspiegeling in uw app wilt uitschakelen, stelt u de JsonSerializerIsReflectionEnabledByDefault eigenschap false MSBuild in op in uw projectbestand:

<PropertyGroup>
  <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>
  • Het gedrag van deze eigenschap is consistent, ongeacht runtime, CoreCLR of Native AOT.
  • Als u deze eigenschap niet opgeeft en PublishTrimmed is ingeschakeld, wordt serialisatie op basis van reflectie automatisch uitgeschakeld.

U kunt programmatisch controleren of weerspiegeling is uitgeschakeld met behulp van de JsonSerializer.IsReflectionEnabledByDefault eigenschap. In het volgende codefragment ziet u hoe u uw serializer kunt configureren, afhankelijk van of weerspiegeling is ingeschakeld:

static JsonSerializerOptions CreateDefaultOptions()
{
    return new()
    {
        TypeInfoResolver = JsonSerializer.IsReflectionEnabledByDefault
            ? new DefaultJsonTypeInfoResolver()
            : MyContext.Default
    };
}

Omdat de eigenschap wordt behandeld als een koppelingstijdconstante, roott de vorige methode de op weerspiegeling gebaseerde resolver niet in toepassingen die worden uitgevoerd in Systeemeigen AOT.

Opties opgeven

In .NET 8 en latere versies kunnen de meeste opties die u kunt instellen, ook worden ingesteld JsonSerializerOptions met behulp van het JsonSourceGenerationOptionsAttribute kenmerk. Het voordeel van het instellen van opties via het kenmerk is dat de configuratie tijdens het compileren wordt opgegeven, waardoor de gegenereerde MyContext.Default eigenschap vooraf wordt geconfigureerd met alle relevante optieset.

De volgende code laat zien hoe u opties instelt met behulp van het JsonSourceGenerationOptionsAttribute kenmerk.

[JsonSourceGenerationOptions(
    WriteIndented = true,
    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
    GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SerializationModeOptionsContext : JsonSerializerContext
{
}

Wanneer u JsonSourceGenerationOptionsAttribute serialisatieopties opgeeft, roept u een van de volgende serialisatiemethoden aan:

  • Een JsonSerializer.Serialize methode die een TypeInfo<TValue>. Geef deze door aan de Default.<TypeName> eigenschap van uw contextklasse:

    jsonString = JsonSerializer.Serialize(
        weatherForecast, SerializationModeOptionsContext.Default.WeatherForecast);
    
  • Een JsonSerializer.Serialize methode die een context gebruikt. Geef deze door aan de Default statische eigenschap van uw contextklasse.

    jsonString = JsonSerializer.Serialize(
        weatherForecast, typeof(WeatherForecast), SerializationModeOptionsContext.Default);
    

Als u een methode aanroept waarmee u uw eigen exemplaar kunt Utf8JsonWriterdoorgeven, wordt de instelling van Indented de schrijver gehonoreerd in plaats van de JsonSourceGenerationOptionsAttribute.WriteIndented optie.

Als u een contextexemplaren maakt en gebruikt door de constructor aan te roepen die een JsonSerializerOptions exemplaar gebruikt, wordt het opgegeven exemplaar gebruikt in plaats van de opties die zijn opgegeven door JsonSourceGenerationOptionsAttribute.

Hier volgen de voorgaande voorbeelden in een volledig programma:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace SerializeOnlyWithOptions
{
    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    [JsonSourceGenerationOptions(
        WriteIndented = true,
        PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
        GenerationMode = JsonSourceGenerationMode.Serialization)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class SerializationModeOptionsContext : JsonSerializerContext
    {
    }
    public class Program
    {
        public static void Main()
        {
            string jsonString;
            WeatherForecast weatherForecast = new()
                { Date = DateTime.Parse("2019-08-01"), TemperatureCelsius = 25, Summary = "Hot" };

            // Serialize using TypeInfo<TValue> provided by the context
            // and options specified by [JsonSourceGenerationOptions].
            jsonString = JsonSerializer.Serialize(
                weatherForecast, SerializationModeOptionsContext.Default.WeatherForecast);
            Console.WriteLine(jsonString);
            // output:
            //{
            //  "date": "2019-08-01T00:00:00",
            //  "temperatureCelsius": 0,
            //  "summary": "Hot"
            //}

            // Serialize using Default context
            // and options specified by [JsonSourceGenerationOptions].
            jsonString = JsonSerializer.Serialize(
                weatherForecast, typeof(WeatherForecast), SerializationModeOptionsContext.Default);
            Console.WriteLine(jsonString);
            // output:
            //{
            //  "date": "2019-08-01T00:00:00",
            //  "temperatureCelsius": 0,
            //  "summary": "Hot"
            //}
        }
    }
}

Opties opgeven met behulp van JsonSerializerOptions

Sommige opties kunnen niet worden ingesteld met behulp van JsonSerializerOptionsJsonSourceGenerationOptionsAttribute. Opties opgeven met behulp van JsonSerializerOptions:

  • Maak een instantie van JsonSerializerOptions.
  • Maak een exemplaar van uw klasse dat is afgeleid van JsonSerializerContexten geef het JsonSerializerOptions exemplaar door aan de constructor.
  • Serialisatie- of deserialisatiemethoden aanroepen van JsonSerializer die een contextexemplaren of TypeInfo<TValue>.

Hier volgt een voorbeeldcontextklasse, gevolgd door serialisatie- en deserialisatievoorbeeldcode:

[JsonSerializable(typeof(WeatherForecast))]
internal partial class OptionsExampleContext : JsonSerializerContext
{
}
jsonString = JsonSerializer.Serialize(
    weatherForecast,
    typeof(WeatherForecast),
    new OptionsExampleContext(
        new JsonSerializerOptions(JsonSerializerDefaults.Web)));
weatherForecast = JsonSerializer.Deserialize(
    jsonString, 
    typeof(WeatherForecast), 
    new OptionsExampleContext(
        new JsonSerializerOptions(JsonSerializerDefaults.Web)))
        as WeatherForecast;

Hier volgen de voorgaande voorbeelden in een volledig programma:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonSerializerOptionsExample
{
    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class OptionsExampleContext : JsonSerializerContext
    {
    }

    public class Program
    {
        public static void Main()
        {
            string jsonString = """
                {
                  "date": "2019-08-01T00:00:00",
                  "temperatureCelsius": 25,
                  "summary": "Hot"
                }
                """;
            WeatherForecast? weatherForecast;

            weatherForecast = JsonSerializer.Deserialize(
                jsonString, 
                typeof(WeatherForecast), 
                new OptionsExampleContext(
                    new JsonSerializerOptions(JsonSerializerDefaults.Web)))
                    as WeatherForecast;
            Console.WriteLine($"Date={weatherForecast?.Date}");
            // output:
            //Date=8/1/2019 12:00:00 AM

            jsonString = JsonSerializer.Serialize(
                weatherForecast,
                typeof(WeatherForecast),
                new OptionsExampleContext(
                    new JsonSerializerOptions(JsonSerializerDefaults.Web)));
            Console.WriteLine(jsonString);
            // output:
            //{ "date":"2019-08-01T00:00:00","temperatureCelsius":25,"summary":"Hot"}
        }
    }
}

Brongeneratoren combineren

U kunt contracten combineren vanuit meerdere door de bron gegenereerde contexten binnen één JsonSerializerOptions exemplaar. Gebruik de JsonSerializerOptions.TypeInfoResolver eigenschap om meerdere contexten te koppelen die zijn gecombineerd met behulp van de JsonTypeInfoResolver.Combine(IJsonTypeInfoResolver[]) methode.

var options = new JsonSerializerOptions
{
    TypeInfoResolver = JsonTypeInfoResolver.Combine(ContextA.Default, ContextB.Default, ContextC.Default);
};

Als u vanaf .NET 8 later een andere context wilt voorbereiden of toevoegen, kunt u dit doen met behulp van de JsonSerializerOptions.TypeInfoResolverChain eigenschap. De volgorde van de keten is belangrijk: JsonSerializerOptions voert query's uit op elk van de resolvers in hun opgegeven volgorde en retourneert het eerste resultaat dat niet null is.

options.TypeInfoResolverChain.Add(ContextD.Default); // Append to the end of the list.
options.TypeInfoResolverChain.Insert(0, ContextE.Default); // Insert at the beginning of the list.

Wijzigingen die in de TypeInfoResolverChain eigenschap zijn aangebracht, worden doorgevoerd door TypeInfoResolver en omgekeerd.

Opsommingsvelden als tekenreeksen serialiseren

Opsommingen worden standaard geserialiseerd als getallen. Als u de velden van een specifieke opsomming wilt serialiseren als tekenreeksen bij het genereren van de bron, maakt u er aantekeningen bij met het JsonStringEnumConverter<TEnum> conversieprogramma. Of als u een dekenbeleid voor alle opsommingen wilt instellen, gebruikt u het JsonSourceGenerationOptionsAttribute kenmerk.

JsonStringEnumConverter<T> Converter

Als u opsommingsnamen wilt serialiseren als tekenreeksen met behulp van brongeneratie, gebruikt u het JsonStringEnumConverter<TEnum> conversieprogramma. (Het niet-algemene JsonStringEnumConverter type wordt niet ondersteund door de systeemeigen AOT-runtime.)

Aantekeningen toevoegen aan het opsommingstype met het JsonStringEnumConverter<TEnum> conversieprogramma met behulp van het JsonConverterAttribute kenmerk:

public class WeatherForecastWithPrecipEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Precipitation? Precipitation { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter<Precipitation>))]
public enum Precipitation
{
    Drizzle, Rain, Sleet, Hail, Snow
}

Maak een JsonSerializerContext klasse en annotaeer deze met het JsonSerializableAttribute kenmerk:

[JsonSerializable(typeof(WeatherForecastWithPrecipEnum))]
public partial class Context1 : JsonSerializerContext { }

Met de volgende code worden de enumnamen geserialiseerd in plaats van de numerieke waarden:

var weatherForecast = new WeatherForecastWithPrecipEnum
{
    Date = DateTime.Parse("2019-08-01"),
    TemperatureCelsius = 25,
    Precipitation = Precipitation.Sleet
};

var options = new JsonSerializerOptions
{
    WriteIndented = true,
    TypeInfoResolver = Context1.Default,
};
string? jsonString = JsonSerializer.Serialize(weatherForecast, options);

De resulterende JSON ziet eruit als in het volgende voorbeeld:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Precipitation": "Sleet"
}

Dekenbeleid

In plaats van het JsonStringEnumConverter<TEnum> type te gebruiken, kunt u een dekenbeleid toepassen om opsommingen als tekenreeksen te serialiseren met behulp van de JsonSourceGenerationOptionsAttribute. Maak een JsonSerializerContext klasse en annotaat met de JsonSerializableAttributeen JsonSourceGenerationOptionsAttribute kenmerken:

[JsonSourceGenerationOptions(UseStringEnumConverter = true)]
[JsonSerializable(typeof(WeatherForecast2WithPrecipEnum))]
public partial class Context2 : JsonSerializerContext { }

U ziet dat de opsomming het volgende niet heeft JsonConverterAttribute:

public class WeatherForecast2WithPrecipEnum
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public Precipitation2? Precipitation { get; set; }
}

public enum Precipitation2
{
    Drizzle, Rain, Sleet, Hail, Snow
}

Zie ook