diff --git a/snippets/core/system-text-json/csharp/DateTimeOffsetNullHandlingConverter.cs b/snippets/core/system-text-json/csharp/DateTimeOffsetNullHandlingConverter.cs new file mode 100644 index 00000000000..846f600b6b8 --- /dev/null +++ b/snippets/core/system-text-json/csharp/DateTimeOffsetNullHandlingConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class DateTimeOffsetNullHandlingConverter : JsonConverter + + { + public override DateTimeOffset Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return default; + } + return reader.GetDateTimeOffset(); + } + + public override void Write( + Utf8JsonWriter writer, + DateTimeOffset value, + JsonSerializerOptions options) + { + writer.WriteStringValue(value); + } + } +} diff --git a/snippets/core/system-text-json/csharp/ConvertInferredTypesToObject.cs b/snippets/core/system-text-json/csharp/DeserializeInferredTypesToObject.cs similarity index 96% rename from snippets/core/system-text-json/csharp/ConvertInferredTypesToObject.cs rename to snippets/core/system-text-json/csharp/DeserializeInferredTypesToObject.cs index efa2f7669e4..dc5efced269 100644 --- a/snippets/core/system-text-json/csharp/ConvertInferredTypesToObject.cs +++ b/snippets/core/system-text-json/csharp/DeserializeInferredTypesToObject.cs @@ -3,7 +3,7 @@ namespace SystemTextJsonSamples { - public class ConvertInferredTypesToObject + public class DeserializeInferredTypesToObject { public static void Run() { diff --git a/snippets/core/system-text-json/csharp/DeserializeNullToNonnullableType.cs b/snippets/core/system-text-json/csharp/DeserializeNullToNonnullableType.cs new file mode 100644 index 00000000000..5a65982ced2 --- /dev/null +++ b/snippets/core/system-text-json/csharp/DeserializeNullToNonnullableType.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class DeserializeNullToNonnullableType + { + public static void Run() + { + string jsonString; + var wf = WeatherForecastFactories.CreateWeatherForecast(); + + var serializeOptions = new JsonSerializerOptions(); + serializeOptions.WriteIndented = true; + serializeOptions.Converters.Add(new DateTimeOffsetNullHandlingConverter()); + jsonString = JsonSerializer.Serialize(wf, serializeOptions); + Console.WriteLine($"JSON with valid Date:\n{jsonString}\n"); + + var deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new DateTimeOffsetNullHandlingConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + wf.DisplayPropertyValues(); + + jsonString = @"{""Date"": null,""TemperatureCelsius"": 25,""Summary"":""Hot""}"; + Console.WriteLine($"JSON with null Date:\n{jsonString}\n"); + + // The missing-date JSON deserializes with error if the converter isn't used. + try + { + wf = JsonSerializer.Deserialize(jsonString); + } + catch (Exception ex) + { + Console.WriteLine($"Exception thrown: {ex.Message}\n"); + } + + Console.WriteLine("Deserialize with converter"); + deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new DateTimeOffsetNullHandlingConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + wf.DisplayPropertyValues(); + } + } + +} diff --git a/snippets/core/system-text-json/csharp/DeserializeRequiredProperty.cs b/snippets/core/system-text-json/csharp/DeserializeRequiredProperty.cs new file mode 100644 index 00000000000..fdb87b2380e --- /dev/null +++ b/snippets/core/system-text-json/csharp/DeserializeRequiredProperty.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class DeserializeRequiredProperty + { + public static void Run() + { + string jsonString; + var wf = WeatherForecastFactories.CreateWeatherForecast(); + + var serializeOptions = new JsonSerializerOptions(); + serializeOptions.WriteIndented = true; + serializeOptions.Converters.Add(new WeatherForecastRequiredPropertyConverter()); + jsonString = JsonSerializer.Serialize(wf, serializeOptions); + Console.WriteLine($"JSON with Date:\n{jsonString}\n"); + + var deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new WeatherForecastRequiredPropertyConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + wf.DisplayPropertyValues(); + + jsonString = @"{""TemperatureCelsius"": 25,""Summary"":""Hot""}"; + Console.WriteLine($"JSON without Date:\n{jsonString}\n"); + + // The missing-date JSON deserializes without error if the converter isn't used. + Console.WriteLine("Deserialize without converter"); + wf = JsonSerializer.Deserialize(jsonString); + wf.DisplayPropertyValues(); + + Console.WriteLine("Deserialize with converter"); + try + { + deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new WeatherForecastRequiredPropertyConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + } + catch (Exception ex) + { + Console.WriteLine($"Exception thrown: {ex.Message}\n"); + } + // wf object is unchanged if exception is thrown. + wf.DisplayPropertyValues(); + } + } + +} diff --git a/snippets/core/system-text-json/csharp/ImmutablePoint.cs b/snippets/core/system-text-json/csharp/ImmutablePoint.cs new file mode 100644 index 00000000000..9a47ed7793d --- /dev/null +++ b/snippets/core/system-text-json/csharp/ImmutablePoint.cs @@ -0,0 +1,19 @@ +namespace SystemTextJsonSamples +{ + // + public struct ImmutablePoint + { + private readonly int _x; + private readonly int _y; + + public ImmutablePoint(int x, int y) + { + _x = x; + _y = y; + } + + public int X { get { return _x; } } + public int Y { get { return _y; } } + } + // +} diff --git a/snippets/core/system-text-json/csharp/ImmutablePointConverter.cs b/snippets/core/system-text-json/csharp/ImmutablePointConverter.cs new file mode 100644 index 00000000000..a45d657e790 --- /dev/null +++ b/snippets/core/system-text-json/csharp/ImmutablePointConverter.cs @@ -0,0 +1,112 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class ImmutablePointConverter : JsonConverter + + { + private const string XName = "X"; + private const string YName = "Y"; + + public override ImmutablePoint Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + }; + + int x = default; + bool xSet = false; + + int y = default; + bool ySet = false; + + // Get the first property. + reader.Read(); + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + string propertyName = reader.GetString(); + if (propertyName == XName) + { + x = ReadProperty(ref reader, options); + xSet = true; + } + else if (propertyName == YName) + { + y = ReadProperty(ref reader, options); + ySet = true; + } + else + { + throw new JsonException(); + } + + // Get the second property. + reader.Read(); + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } + + propertyName = reader.GetString(); + if (propertyName == XName) + { + x = ReadProperty(ref reader, options); + xSet = true; + } + else if (propertyName == YName) + { + y = ReadProperty(ref reader, options); + ySet = true; + } + else + { + throw new JsonException(); + } + + if (!xSet || !ySet) + { + throw new JsonException(); + } + + reader.Read(); + + if (reader.TokenType != JsonTokenType.EndObject) + { + throw new JsonException(); + } + + return new ImmutablePoint(x, y); + } + + public int ReadProperty(ref Utf8JsonReader reader, JsonSerializerOptions options) + { + if (options?.GetConverter(typeof(int)) is JsonConverter intConverter) + { + reader.Read(); + return intConverter.Read(ref reader, typeof(int), options); + } + else + { + throw new JsonException(); + } + } + + public override void Write( + Utf8JsonWriter writer, + ImmutablePoint value, + JsonSerializerOptions options) + { + // Don't pass in options when recursively calling Serialize. + JsonSerializer.Serialize(writer, value); + } + } +} diff --git a/snippets/core/system-text-json/csharp/LongToStringConverter.cs b/snippets/core/system-text-json/csharp/LongToStringConverter.cs new file mode 100644 index 00000000000..e671104602c --- /dev/null +++ b/snippets/core/system-text-json/csharp/LongToStringConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Buffers; +using System.Buffers.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class LongToStringConverter : JsonConverter + { + public override long Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + ReadOnlySpan span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; + if (Utf8Parser.TryParse(span, out long number, out int bytesConsumed) && span.Length == bytesConsumed) + return number; + + if (Int64.TryParse(reader.GetString(), out number)) + return number; + } + + return reader.GetInt64(); + } + + public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } + } +} diff --git a/snippets/core/system-text-json/csharp/Program.cs b/snippets/core/system-text-json/csharp/Program.cs index a36a5f33246..27d4e739c7f 100644 --- a/snippets/core/system-text-json/csharp/Program.cs +++ b/snippets/core/system-text-json/csharp/Program.cs @@ -71,13 +71,31 @@ static async Task Main(string[] args) RegisterConverterWithAttributeOnType.Run(); Console.WriteLine("\n============================= Custom converter Dictionary with TKey = Enum\n"); - ConvertDictionaryTkeyEnumTValue.Run(); + RoundtripDictionaryTkeyEnumTValue.Run(); Console.WriteLine("\n============================= Custom converter Polymorphic\n"); - ConvertPolymorphic.Run(); + RoundtripPolymorphic.Run(); Console.WriteLine("\n============================= Custom converter inferred types to Object\n"); - ConvertInferredTypesToObject.Run(); + DeserializeInferredTypesToObject.Run(); + + Console.WriteLine("\n============================= Custom converter long to string\n"); + RoundtripLongToString.Run(); + + Console.WriteLine("\n============================= Callbacks\n"); + RoundtripCallbacks.Run(); + + Console.WriteLine("\n============================= Required property\n"); + DeserializeRequiredProperty.Run(); + + Console.WriteLine("\n============================= Null value to nonnullable type\n"); + DeserializeNullToNonnullableType.Run(); + + Console.WriteLine("\n============================= Immutable struct\n"); + RoundtripImmutableStruct.Run(); + + Console.WriteLine("\n============================= Runtime property exclusion\n"); + SerializeRuntimePropertyExclusion.Run(); Console.WriteLine("\n============================= JsonDocument data access\n"); JsonDocumentDataAccess.Run(); diff --git a/snippets/core/system-text-json/csharp/RoundtripCallbacks.cs b/snippets/core/system-text-json/csharp/RoundtripCallbacks.cs new file mode 100644 index 00000000000..8e06a2d93f9 --- /dev/null +++ b/snippets/core/system-text-json/csharp/RoundtripCallbacks.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class RoundtripCallbacks + { + public static void Run() + { + string jsonString; + var wf = WeatherForecastFactories.CreateWeatherForecast(); + wf.DisplayPropertyValues(); + + // + var serializeOptions = new JsonSerializerOptions(); + serializeOptions.Converters.Add(new WeatherForecastCallbacksConverter()); + serializeOptions.WriteIndented = true; + jsonString = JsonSerializer.Serialize(wf, serializeOptions); + // + + Console.WriteLine($"JSON output:\n{jsonString}\n"); + //jsonString = @"{""Date"": null,""TemperatureCelsius"": 25,""Summary"":""Hot""}"; + + // + var deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new WeatherForecastCallbacksConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + // + + wf.DisplayPropertyValues(); + } + } + +} diff --git a/snippets/core/system-text-json/csharp/ConvertDictionaryTkeyEnumTValue.cs b/snippets/core/system-text-json/csharp/RoundtripDictionaryTkeyEnumTValue.cs similarity index 95% rename from snippets/core/system-text-json/csharp/ConvertDictionaryTkeyEnumTValue.cs rename to snippets/core/system-text-json/csharp/RoundtripDictionaryTkeyEnumTValue.cs index d783a9cc497..851694efb56 100644 --- a/snippets/core/system-text-json/csharp/ConvertDictionaryTkeyEnumTValue.cs +++ b/snippets/core/system-text-json/csharp/RoundtripDictionaryTkeyEnumTValue.cs @@ -3,7 +3,7 @@ namespace SystemTextJsonSamples { - public class ConvertDictionaryTkeyEnumTValue + public class RoundtripDictionaryTkeyEnumTValue { public static void Run() { diff --git a/snippets/core/system-text-json/csharp/RoundtripImmutableStruct.cs b/snippets/core/system-text-json/csharp/RoundtripImmutableStruct.cs new file mode 100644 index 00000000000..e53ea0fa427 --- /dev/null +++ b/snippets/core/system-text-json/csharp/RoundtripImmutableStruct.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Xml.Schema; + +namespace SystemTextJsonSamples +{ + public class RoundtripImmutableStruct + { + public static void Run() + { + string jsonString; + var point1 = new ImmutablePoint(1, 2); + var point2 = new ImmutablePoint(3, 4); + var points = new List { point1, point2 }; + + var serializeOptions = new JsonSerializerOptions(); + serializeOptions.WriteIndented = true; + //serializeOptions.Converters.Add(new WeatherForecastRequiredPropertyConverter()); + jsonString = JsonSerializer.Serialize(points, serializeOptions); + Console.WriteLine($"JSON output:\n{jsonString}\n"); + + var deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new ImmutablePointConverter()); + points = JsonSerializer.Deserialize>(jsonString, deserializeOptions); + Console.WriteLine("Deserialized object values"); + foreach (ImmutablePoint point in points) + { + Console.WriteLine($"X,Y = {point.X},{point.Y}"); + } + } + } + +} diff --git a/snippets/core/system-text-json/csharp/RoundtripLongToString.cs b/snippets/core/system-text-json/csharp/RoundtripLongToString.cs new file mode 100644 index 00000000000..20c1c21d41c --- /dev/null +++ b/snippets/core/system-text-json/csharp/RoundtripLongToString.cs @@ -0,0 +1,25 @@ +using System; +using System.Text.Json; + +namespace SystemTextJsonSamples +{ + public class RoundtripLongToString + { + public static void Run() + { + string jsonString; + + // Serialize to create input JSON + var weatherForecast = WeatherForecastFactories.CreateWeatherForecastWithLong(); + var serializeOptions = new JsonSerializerOptions + { + WriteIndented = true + }; + jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions); + Console.WriteLine($"JSON output:\n{jsonString}\n"); + + weatherForecast = JsonSerializer.Deserialize(jsonString); + weatherForecast.DisplayPropertyValues(); + } + } +} diff --git a/snippets/core/system-text-json/csharp/ConvertPolymorphic.cs b/snippets/core/system-text-json/csharp/RoundtripPolymorphic.cs similarity index 96% rename from snippets/core/system-text-json/csharp/ConvertPolymorphic.cs rename to snippets/core/system-text-json/csharp/RoundtripPolymorphic.cs index cb76d4d0460..a771f16132e 100644 --- a/snippets/core/system-text-json/csharp/ConvertPolymorphic.cs +++ b/snippets/core/system-text-json/csharp/RoundtripPolymorphic.cs @@ -5,7 +5,7 @@ namespace SystemTextJsonSamples { - public class ConvertPolymorphic + public class RoundtripPolymorphic { public static void Run() { diff --git a/snippets/core/system-text-json/csharp/RoundtripToFileAsync.cs b/snippets/core/system-text-json/csharp/RoundtripToFileAsync.cs index 21581672631..f46e5d2dde2 100644 --- a/snippets/core/system-text-json/csharp/RoundtripToFileAsync.cs +++ b/snippets/core/system-text-json/csharp/RoundtripToFileAsync.cs @@ -11,6 +11,7 @@ class RoundtripToFileAsync public static async Task RunAsync() { string fileName = "WeatherForecastAsync.json"; + string fileNameUtf8 = "WeatherForecastAsyncUtf8"; var weatherForecast = WeatherForecastFactories.CreateWeatherForecast(); weatherForecast.DisplayPropertyValues(); @@ -29,6 +30,24 @@ public static async Task RunAsync() } // weatherForecast.DisplayPropertyValues(); + + using (FileStream fs = File.Create(fileNameUtf8)) + { + using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8)) + { + await JsonSerializer.SerializeAsync(fs, weatherForecast); + } + } + Console.WriteLine($"The result is in {fileNameUtf8}\n"); + using (FileStream fs = File.OpenRead(fileNameUtf8)) + { + //System.Text.Json.JsonException: '0xEF' is invalid after a single JSON value. Expected end of data. + //weatherForecast = await JsonSerializer.DeserializeAsync(fs); + } + // + weatherForecast.DisplayPropertyValues(); + + } } } diff --git a/snippets/core/system-text-json/csharp/SerializeRuntimePropertyExclusion.cs b/snippets/core/system-text-json/csharp/SerializeRuntimePropertyExclusion.cs new file mode 100644 index 00000000000..e56a036aa88 --- /dev/null +++ b/snippets/core/system-text-json/csharp/SerializeRuntimePropertyExclusion.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class SerializeRuntimePropertyExclusion + { + public static void Run() + { + string jsonString; + var wf = WeatherForecastFactories.CreateWeatherForecast(); + wf.DisplayPropertyValues(); + + var serializeOptions = new JsonSerializerOptions(); + serializeOptions.Converters.Add(new WeatherForecastRuntimeIgnoreConverter()); + serializeOptions.WriteIndented = true; + jsonString = JsonSerializer.Serialize(wf, serializeOptions); + Console.WriteLine($"JSON output:\n{jsonString}\n"); + + wf.Summary = "N/A"; + wf.DisplayPropertyValues(); + serializeOptions = new JsonSerializerOptions(); + serializeOptions.Converters.Add(new WeatherForecastRuntimeIgnoreConverter()); + serializeOptions.WriteIndented = true; + jsonString = JsonSerializer.Serialize(wf, serializeOptions); + Console.WriteLine($"JSON output:\n{jsonString}\n"); + + var deserializeOptions = new JsonSerializerOptions(); + deserializeOptions.Converters.Add(new WeatherForecastRuntimeIgnoreConverter()); + wf = JsonSerializer.Deserialize(jsonString, deserializeOptions); + wf.DisplayPropertyValues(); + } + } + +} diff --git a/snippets/core/system-text-json/csharp/WeatherForecast.cs b/snippets/core/system-text-json/csharp/WeatherForecast.cs index afdb75c9c13..7b9a6771393 100644 --- a/snippets/core/system-text-json/csharp/WeatherForecast.cs +++ b/snippets/core/system-text-json/csharp/WeatherForecast.cs @@ -13,6 +13,16 @@ public class WeatherForecast } // + // + public class WeatherForecastWithLong + { + public DateTimeOffset Date { get; set; } + [JsonConverter(typeof(LongToStringConverter))] + public long TemperatureCelsius { get; set; } + public string Summary { get; set; } + } + // + // public class WeatherForecastWithDefault { @@ -171,6 +181,12 @@ public static void DisplayPropertyValues(this WeatherForecast wf) Console.WriteLine(); } + public static void DisplayPropertyValues(this WeatherForecastWithLong wf) + { + Utilities.DisplayPropertyValues(wf); + Console.WriteLine(); + } + public static void DisplayPropertyValues(this WeatherForecastWithDefault wf) { Utilities.DisplayPropertyValues(wf); @@ -289,6 +305,17 @@ public static WeatherForecast CreateWeatherForecast() return weatherForecast; } + public static WeatherForecastWithLong CreateWeatherForecastWithLong() + { + var weatherForecast = new WeatherForecastWithLong + { + Date = DateTime.Parse("2019-08-01"), + TemperatureCelsius = 25, + Summary = "Hot" + }; + return weatherForecast; + } + public static WeatherForecastWithROProperty CreateWeatherForecastWithROProperty() { var weatherForecast = new WeatherForecastWithROProperty diff --git a/snippets/core/system-text-json/csharp/WeatherForecastCallbacksConverter.cs b/snippets/core/system-text-json/csharp/WeatherForecastCallbacksConverter.cs new file mode 100644 index 00000000000..c5b364eab82 --- /dev/null +++ b/snippets/core/system-text-json/csharp/WeatherForecastCallbacksConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class WeatherForecastCallbacksConverter : JsonConverter + { + public override WeatherForecast Read( + ref Utf8JsonReader reader, + Type type, + JsonSerializerOptions options) + { + // Place "before" code here (OnDeserializing), but note that there is no access here to the POCO instance. + Console.WriteLine("OnDeserializing"); + + // Don't pass in options when recursively calling Deserialize. + WeatherForecast value = JsonSerializer.Deserialize(ref reader); + + // Place "after" code here (OnDeserialized) + Console.WriteLine("OnDeserialized"); + + return value; + } + + public override void Write( + Utf8JsonWriter writer, + WeatherForecast value, JsonSerializerOptions options) + { + // Place "before" code here (OnSerializing) + Console.WriteLine("OnSerializing"); + + // Don't pass in options when recursively calling Serialize. + JsonSerializer.Serialize(writer, value); + + // Place "after" code here (OnSerialized) + Console.WriteLine("OnSerialized"); + } + } +} diff --git a/snippets/core/system-text-json/csharp/WeatherForecastRequiredPropertyConverter.cs b/snippets/core/system-text-json/csharp/WeatherForecastRequiredPropertyConverter.cs new file mode 100644 index 00000000000..ed7e8ec2225 --- /dev/null +++ b/snippets/core/system-text-json/csharp/WeatherForecastRequiredPropertyConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class WeatherForecastRequiredPropertyConverter : JsonConverter + { + public override WeatherForecast Read( + ref Utf8JsonReader reader, + Type type, + JsonSerializerOptions options) + { + // Don't pass in options when recursively calling Deserialize. + WeatherForecast value = JsonSerializer.Deserialize(ref reader); + + // Check for required fields set by values in JSON + if (value.Date == default) + { + throw new JsonException("Required property not received in the JSON"); + }; + return value; + } + + public override void Write( + Utf8JsonWriter writer, + WeatherForecast value, JsonSerializerOptions options) + { + // Don't pass in options when recursively calling Serialize. + JsonSerializer.Serialize(writer, value); + } + } +} diff --git a/snippets/core/system-text-json/csharp/WeatherForecastRuntimeIgnoreConverter.cs b/snippets/core/system-text-json/csharp/WeatherForecastRuntimeIgnoreConverter.cs new file mode 100644 index 00000000000..28f266ec7af --- /dev/null +++ b/snippets/core/system-text-json/csharp/WeatherForecastRuntimeIgnoreConverter.cs @@ -0,0 +1,70 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SystemTextJsonSamples +{ + public class WeatherForecastRuntimeIgnoreConverter : JsonConverter + { + public override WeatherForecast Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException(); + } + + var wf = new WeatherForecast(); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return wf; + } + + if (reader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = reader.GetString(); + reader.Read(); + switch (propertyName) + { + case "Date": + DateTimeOffset date = reader.GetDateTimeOffset(); + wf.Date = date; + break; + case "TemperatureCelsius": + int temperatureCelsius = reader.GetInt32(); + wf.TemperatureCelsius = temperatureCelsius; + break; + case "Summary": + string summary = reader.GetString(); + wf.Summary = string.IsNullOrWhiteSpace(summary) ? "N/A" : summary; + break; + } + } + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, WeatherForecast wf, JsonSerializerOptions options) + { + // Location for OnSerializing "callback" code. + Console.WriteLine("OnSerializing"); + + writer.WriteStartObject(); + + writer.WriteString("Date", wf.Date); + writer.WriteNumber("TemperatureCelsius", wf.TemperatureCelsius); + if (!string.IsNullOrWhiteSpace(wf.Summary) && wf.Summary != "N/A") + { + writer.WriteString("Summary", wf.Summary); + } + + writer.WriteEndObject(); + } + } +}