Megosztás a következőn keresztül:


A forráslétrehozás használata System.Text.Json

A forráslétrehozás System.Text.Json a .NET 6-os és újabb verzióiban érhető el. Ha egy alkalmazásban használják, az alkalmazás nyelvének C# 9.0-s vagy újabb verziójának kell lennie. Ez a cikk bemutatja, hogyan használhatja a forrásgeneráció által támogatott szerializációt az alkalmazásokban.

A különböző forrásgenerációs módokról további információt a Forrás-generációs módok című témakörben talál.

Forrásgenerálási alapértelmezett értékek használata

A forráslétrehozás használata az összes alapértelmezett beállítással (mindkét mód, alapértelmezett beállítás):

  1. Hozzon létre egy részleges osztályt, amely a forrásból JsonSerializerContextszármazik.

  2. Adja meg a szerializálni vagy deszerializálni kívánt típust a környezeti osztályra való alkalmazással JsonSerializableAttribute .

  3. Hívjon meg egy metódust JsonSerializer , amely vagy:

Alapértelmezés szerint mindkét forrásgenerálási mód használható, ha nem ad meg egyet. A használni kívánt mód megadásáról a cikk későbbi részében, a forrásgenerálási mód megadása című témakörben talál további információt.

Az alábbi példákban használt típus:

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

Az alábbi környezeti osztály konfigurálva van a forráslétrehozáshoz WeatherForecast az előző osztályhoz:

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

A tagok típusait WeatherForecast nem kell explicit módon megadni attribútumokkal [JsonSerializable] . A szabály alól kivételként object deklarált tagok. Meg kell adni a deklarált object tag futtatókörnyezet-típusát. Tegyük fel például, hogy a következő osztályt tartalmazza:

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

És tudod, hogy futásidőben lehet, hogy rendelkezik boolean és int objektumok:

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

Ezután boolean deklarálni int kell a következőt [JsonSerializable]:

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

A gyűjtemény forrásgenerációjának megadásához használja [JsonSerializable] a gyűjtemény típusát. Például: [JsonSerializable(typeof(List<WeatherForecast>))]

JsonSerializer forrásgenerálást használó metódusok

Az alábbi példákban a környezettípus statikus Default tulajdonsága a környezettípus egy példányát adja meg alapértelmezett beállításokkal. A környezeti példány egy olyan tulajdonságot WeatherForecast biztosít, amely egy példányt JsonTypeInfo<WeatherForecast> ad vissza. Ennek a tulajdonságnak TypeInfoPropertyName a nevét az attribútum tulajdonságával [JsonSerializable] adhatja meg.

Szerializálási példák

A következő használatával JsonTypeInfo<T>:

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

A következő használatával JsonSerializerContext:

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

A következő használatával JsonSerializerOptions:

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

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

Deszerializálási példák

A következő használatával JsonTypeInfo<T>:

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

A következő használatával JsonSerializerContext:

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

A következő használatával JsonSerializerOptions:

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

Példa a teljes programra

A teljes programban az alábbi példákat mutatjuk be:

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"}
        }
    }
}

Forrásgenerálási mód megadása

Metaadat-alapú vagy szerializáció-optimalizálási módot is megadhat egy teljes környezethez, amely több típust is tartalmazhat. Vagy megadhatja az egyes típusokhoz tartozó módot. Ha mindkettőt megteszi, a típus módspecifikációja nyer.

Példa szerializálás-optimalizálás (gyorsútvonal) módra

  • Teljes környezet esetén:

    [JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class SerializeOnlyContext : JsonSerializerContext
    {
    }
    
  • Egyéni típus esetén:

    [JsonSerializable(typeof(WeatherForecast), GenerationMode = JsonSourceGenerationMode.Serialization)]
    internal partial class SerializeOnlyWeatherForecastOnlyContext : JsonSerializerContext
    {
    }
    
  • Példa a teljes programra

    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"}
            }
        }
    }
    

Példa metaadatokon alapuló módra

  • Teljes környezet esetén:

    [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);
    
  • Egyéni típus esetén:

    [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);
    
  • Példa a teljes programra

    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"}
            }
        }
    }
    

Forrásgenerációs támogatás a ASP.NET Core-ban

A Blazor-alkalmazásokban használjon túlterhelési HttpClientJsonExtensions.GetFromJsonAsync és HttpClientJsonExtensions.PostAsJsonAsync bővítménymetelyeket, amelyek forrásgenerálási környezetet vagy TypeInfo<TValue>.

A .NET 8-tól kezdve a bővítménymetodusok túlterhelését HttpClientJsonExtensions.GetFromJsonAsAsyncEnumerable is használhatja, amelyek elfogadják a forrásgenerálási környezetet vagy TypeInfo<TValue>a .

A Razor Pages, az MVC, a SignalR és a Webes API-alkalmazásokban a JsonSerializerOptions.TypeInfoResolver tulajdonság használatával adja meg a környezetet.

[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));

A Razor Pages, az MVC, a SignalR és a Webes API-alkalmazásokban a JsonSerializerOptions.TypeInfoResolver tulajdonság használatával adja meg a környezetet.

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

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

A Razor Pages, az MVC, a SignalR és a Webes API-alkalmazásokban a következő példában látható módon használja a AddContext metódust JsonSerializerOptions:

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

Feljegyzés

JsonSourceGenerationMode.Serializationaz aszinkron szerializálás nem támogatott.

A .NET 7-ben és a korábbi verziókban ez a korlátozás azokat a szinkron túlterheléseket is érinti, amelyek elfogadják JsonSerializer.Serialize a Stream. A .NET 8-tól kezdve annak ellenére, hogy a streamelési szerializálás metaadat-alapú modelleket igényel, a gyors útvonalra fog visszaállni, ha a hasznos adatok elég kicsiek ahhoz, hogy elférjenek az előre meghatározott pufferméretben. További információ: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/#json.

Tükröződés alapértelmezett értékének letiltása

Mivel System.Text.Json alapértelmezés szerint tükröződést használ, egy alapszintű szerializálási módszer meghívása megszakíthatja a natív AOT-alkalmazásokat, ami nem támogatja az összes szükséges tükröződési API-t. Ezeket a töréseket nehéz diagnosztizálni, mivel kiszámíthatatlanok lehetnek, és az alkalmazásokat gyakran a CoreCLR-futtatókörnyezetben hibakereséssel végzik, ahol a tükröződés működik. Ehelyett, ha kifejezetten letiltja a tükröződésalapú szerializálást, a törések könnyebben diagnosztizálhatóak. A tükröződésalapú szerializálást InvalidOperationException használó kód egy leíró üzenetet küld futásidőben.

Ha le szeretné tiltani az alapértelmezett tükröződést az alkalmazásban, állítsa be az JsonSerializerIsReflectionEnabledByDefault MSBuild tulajdonságot false a projektfájlba:

<PropertyGroup>
  <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>
  • A tulajdonság viselkedése futásidőtől függetlenül konzisztens, akár CoreCLR, akár natív AOT.
  • Ha nem adja meg ezt a tulajdonságot, és a PublishTrimmed engedélyezve van, a tükröződésalapú szerializálás automatikusan le lesz tiltva.

A tulajdonság használatával JsonSerializer.IsReflectionEnabledByDefault programozott módon ellenőrizheti, hogy a tükröződés le van-e tiltva. Az alábbi kódrészlet bemutatja, hogyan konfigurálhatja a szerializálót attól függően, hogy engedélyezve van-e a tükröződés:

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

Mivel a tulajdonság csatolási idő állandóként van kezelve, az előző metódus nem gyökerezteti a tükröződésalapú feloldót a natív AOT-ban futó alkalmazásokban.

Beállítások megadása

A .NET 8 és újabb verzióiban a legtöbb beállítás JsonSerializerOptions az attribútummal JsonSourceGenerationOptionsAttribute is beállítható. Az attribútumon keresztüli beállítások beállításának előnye, hogy a konfiguráció fordításkor van megadva, ami biztosítja, hogy a létrehozott MyContext.Default tulajdonság előre konfigurálva legyen az összes vonatkozó beállításkészlettel.

Az alábbi kód bemutatja, hogyan állíthat be beállításokat az JsonSourceGenerationOptionsAttribute attribútum használatával.

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

JsonSourceGenerationOptionsAttribute Szerializálási beállítások megadásakor hívja meg a következő szerializálási módszerek egyikét:

  • Egy JsonSerializer.Serialize metódus, amely egy TypeInfo<TValue>. Adja át a Default.<TypeName> környezeti osztály tulajdonságát:

    jsonString = JsonSerializer.Serialize(
        weatherForecast, SerializationModeOptionsContext.Default.WeatherForecast);
    
  • Egy JsonSerializer.Serialize kontextust használó metódus. Adja át a Default környezeti osztály statikus tulajdonságát.

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

Ha olyan metódust hív meg, amely lehetővé teszi, hogy a saját példányát Utf8JsonWriteradja át, az író beállítását Indented a beállítás helyett a JsonSourceGenerationOptionsAttribute.WriteIndented rendszer tiszteletben tartja.

Ha környezeti példányt hoz létre és használ egy példányt használó JsonSerializerOptions konstruktor meghívásával, a megadott példány lesz használva a megadott JsonSourceGenerationOptionsAttributebeállítások helyett.

A teljes programban az alábbi példákat mutatjuk be:

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"
            //}
        }
    }
}

Beállítások megadása a következő használatával: JsonSerializerOptions

Néhány lehetőség JsonSerializerOptions nem állítható be a következővel JsonSourceGenerationOptionsAttribute: . Beállítások megadása a következő használatával JsonSerializerOptions:

  • Hozza létre a JsonSerializerOptions egy példányát.
  • Hozzon létre egy példányt az osztályból JsonSerializerContext, és adja át a példányt JsonSerializerOptions a konstruktornak.
  • Olyan szerializálási vagy deszerializálási metódusok meghívása JsonSerializer , amelyek környezeti példányt vagy TypeInfo<TValue>.

Íme egy példa környezeti osztály, amelyet szerializálás és deszerializálási példakód követ:

[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;

A teljes programban az alábbi példákat mutatjuk be:

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"}
        }
    }
}

Forrásgenerátorok egyesítése

Egyetlen példányon belül JsonSerializerOptions több forrás által létrehozott környezetből származó szerződéseket egyesíthet. JsonSerializerOptions.TypeInfoResolver A tulajdonság használatával több olyan környezetet is láncba rendezhet, amelyeket a JsonTypeInfoResolver.Combine(IJsonTypeInfoResolver[]) metódussal kombináltak.

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

A .NET 8-tól kezdődően, ha később egy másik környezetet szeretne előszedni vagy hozzáfűzni, ezt a JsonSerializerOptions.TypeInfoResolverChain tulajdonság használatával teheti meg. A lánc sorrendje jelentős: JsonSerializerOptions lekérdezi az egyes feloldókat a megadott sorrendben, és az első nem null eredményt adja vissza.

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.

A tulajdonságon TypeInfoResolverChain végzett minden módosítás tükröződik TypeInfoResolver , és fordítva is.

Számmezők szerializálása sztringként

Alapértelmezés szerint a számokat számként szerializálja a rendszer. Ha egy adott enum mezőit sztringekként szeretné szerializálni a forráslétrehozás használatakor, jegyzetelje meg a JsonStringEnumConverter<TEnum> konverterrel. Vagy ha az összes enumeráláshoz egy keretszabályzatot szeretne beállítani, használja az JsonSourceGenerationOptionsAttribute attribútumot.

JsonStringEnumConverter<T> Converter

Az enumerálási nevek sztringekként való szerializálásához használja a JsonStringEnumConverter<TEnum> konvertert. (A natív AOT-futtatókörnyezet nem támogatja a nem általános JsonStringEnumConverter típust.)

Az enumerálási típus megjegyzése a konverterrel az JsonStringEnumConverter<TEnum>JsonConverterAttribute attribútum használatával:

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
}

Hozzon létre egy osztályt JsonSerializerContext , és jegyzetelje meg az JsonSerializableAttribute attribútummal:

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

A következő kód szerializálja a számértékek helyett az enumerálási neveket:

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);

Az eredményként kapott JSON a következő példához hasonlóan néz ki:

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

Keretszabályzat

A típus használata JsonStringEnumConverter<TEnum> helyett egy keretszabályzatot alkalmazhat az enumerálás sztringekként való szerializálására a JsonSourceGenerationOptionsAttribute. Hozzon létre egy osztálytJsonSerializerContext, és jegyzetelje meg az JsonSourceGenerationOptionsAttributeJsonSerializableAttribute alábbi attribútumokkal:

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

Figyelje meg, hogy az enumerálás nem rendelkezik a következő értékével 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
}

Lásd még