diff --git a/snippets/core/system-text-json/csharp/IForecast.cs b/snippets/core/system-text-json/csharp/IForecast.cs new file mode 100644 index 00000000000..2c0b0c48400 --- /dev/null +++ b/snippets/core/system-text-json/csharp/IForecast.cs @@ -0,0 +1,25 @@ +using System; + +namespace SystemTextJsonSamples +{ + public interface IForecast + { + public DateTimeOffset Date { get; set; } + public int TemperatureCelsius { get; set; } + public string Summary { get; set; } + } + + public class Forecast : IForecast + { + public DateTimeOffset Date { get; set; } + public int TemperatureCelsius { get; set; } + public string Summary { get; set; } + public int WindSpeed { get; set; } + } + + public class Forecasts + { + public IForecast Monday { get; set; } + public object Tuesday { get; set; } + } +} diff --git a/snippets/core/system-text-json/csharp/Program.cs b/snippets/core/system-text-json/csharp/Program.cs index 9e8b183dc59..557a78015bc 100644 --- a/snippets/core/system-text-json/csharp/Program.cs +++ b/snippets/core/system-text-json/csharp/Program.cs @@ -1,4 +1,6 @@ using System; +using System.IO; +using System.Text; using System.Threading.Tasks; namespace SystemTextJsonSamples @@ -106,6 +108,9 @@ static async Task Main(string[] args) Console.WriteLine("\n============================= Utf8Reader from file\n"); Utf8ReaderFromFile.Run(); + string jsonString = File.ReadAllText("Universities.json"); + ValueTextEqualsExample.Run(Encoding.UTF8.GetBytes(jsonString)); + Console.WriteLine("\n============================= Utf8Reader from byte array\n"); Utf8ReaderFromBytes.Run(); diff --git a/snippets/core/system-text-json/csharp/SerializePolymorphic.cs b/snippets/core/system-text-json/csharp/SerializePolymorphic.cs index 9c536681430..a2a3f6c278b 100644 --- a/snippets/core/system-text-json/csharp/SerializePolymorphic.cs +++ b/snippets/core/system-text-json/csharp/SerializePolymorphic.cs @@ -14,35 +14,80 @@ public static void Run() Console.WriteLine("Base class generic type - derived class properties omitted"); // - var serializeOptions = new JsonSerializerOptions + var options = new JsonSerializerOptions { WriteIndented = true }; - jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions); + jsonString = JsonSerializer.Serialize(weatherForecast, options); // Console.WriteLine($"JSON output:\n{jsonString}\n"); Console.WriteLine("Object generic type parameter - derived class properties included"); // - serializeOptions = new JsonSerializerOptions + options = new JsonSerializerOptions { WriteIndented = true }; - jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions); + jsonString = JsonSerializer.Serialize(weatherForecast, options); // Console.WriteLine($"JSON output:\n{jsonString}\n"); Console.WriteLine("GetType() type parameter - derived class properties included"); // - serializeOptions = new JsonSerializerOptions + options = new JsonSerializerOptions { WriteIndented = true }; - jsonString = JsonSerializer.Serialize(weatherForecast, weatherForecast.GetType(), serializeOptions); + jsonString = JsonSerializer.Serialize(weatherForecast, weatherForecast.GetType(), options); // Console.WriteLine($"JSON output:\n{jsonString}\n"); + + Console.WriteLine("Extra properties on interface implementations included only for object properties"); + // + var forecasts = new Forecasts + { + Monday = new Forecast + { + Date = DateTime.Parse("2020-01-06"), + TemperatureCelsius = 10, + Summary = "Cool", + WindSpeed = 8 + }, + Tuesday = new Forecast + { + Date = DateTime.Parse("2020-01-07"), + TemperatureCelsius = 11, + Summary = "Rainy", + WindSpeed = 10 + } + }; + + options = new JsonSerializerOptions + { + WriteIndented = true + }; + jsonString = JsonSerializer.Serialize(forecasts, options); + // + Console.WriteLine($"{jsonString}\n"); + + WeatherForecastWithPrevious weatherForecastWithPrevious = WeatherForecastFactories.CreateWeatherForecastWithPrevious(); + WeatherForecastWithPreviousAsObject weatherForecastWithPreviousAsObject = WeatherForecastFactories.CreateWeatherForecastWithPreviousAsObject(); + + Console.WriteLine("Second level derived class properties included only for object properties"); + // + options = new JsonSerializerOptions + { + WriteIndented = true + }; + jsonString = JsonSerializer.Serialize(weatherForecastWithPreviousAsObject, options); + // + Console.WriteLine($"JSON output with WindSpeed:\n{jsonString}\n"); + jsonString = JsonSerializer.Serialize( + weatherForecastWithPrevious, + options); + Console.WriteLine($"JSON output without WindSpeed:\n{jsonString}\n"); } } } diff --git a/snippets/core/system-text-json/csharp/Utf8ReaderFromFile.cs b/snippets/core/system-text-json/csharp/Utf8ReaderFromFile.cs index ad5b3b898fd..70caa6c16e6 100644 --- a/snippets/core/system-text-json/csharp/Utf8ReaderFromFile.cs +++ b/snippets/core/system-text-json/csharp/Utf8ReaderFromFile.cs @@ -8,25 +8,33 @@ namespace SystemTextJsonSamples public class Utf8ReaderFromFile { private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name"); + private static ReadOnlySpan Utf8Bom => new byte[] { 0xEF, 0xBB, 0xBF }; public static void Run() { - // Read as UTF-16 and transcode to UTF-8 to convert to a Span - string fileName = "Universities.json"; - string jsonString = File.ReadAllText(fileName); - ReadOnlySpan jsonReadOnlySpan = Encoding.UTF8.GetBytes(jsonString); + // ReadAllBytes if the file encoding is UTF-8: + string fileName = "UniversitiesUtf8.json"; + ReadOnlySpan jsonReadOnlySpan = File.ReadAllBytes(fileName); + + // Read past the UTF-8 BOM bytes if a BOM exists. + if (jsonReadOnlySpan.StartsWith(Utf8Bom)) + { + jsonReadOnlySpan = jsonReadOnlySpan.Slice(Utf8Bom.Length); + } + + // Or read as UTF-16 and transcode to UTF-8 to convert to a ReadOnlySpan + //string fileName = "Universities.json"; + //string jsonString = File.ReadAllText(fileName); + //ReadOnlySpan jsonReadOnlySpan = Encoding.UTF8.GetBytes(jsonString); - // Or ReadAllBytes if the file encoding is UTF-8: - //string fileName = "UniversitiesUtf8.json"; - //ReadOnlySpan jsonReadOnlySpan = File.ReadAllBytes(fileName); int count = 0; int total = 0; - var json = new Utf8JsonReader(jsonReadOnlySpan, isFinalBlock: true, state: default); + var reader = new Utf8JsonReader(jsonReadOnlySpan); - while (json.Read()) + while (reader.Read()) { - JsonTokenType tokenType = json.TokenType; + JsonTokenType tokenType = reader.TokenType; switch (tokenType) { @@ -34,11 +42,11 @@ public static void Run() total++; break; case JsonTokenType.PropertyName: - if (json.ValueTextEquals(s_nameUtf8)) + if (reader.ValueTextEquals(s_nameUtf8)) { // Assume valid JSON, known schema - json.Read(); - if (json.GetString().EndsWith("University")) + reader.Read(); + if (reader.GetString().EndsWith("University")) { count++; } diff --git a/snippets/core/system-text-json/csharp/ValueTextEqualsExample.cs b/snippets/core/system-text-json/csharp/ValueTextEqualsExample.cs new file mode 100644 index 00000000000..6b479fcad70 --- /dev/null +++ b/snippets/core/system-text-json/csharp/ValueTextEqualsExample.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Text; +using System.Text.Json; + +namespace SystemTextJsonSamples +{ + public class ValueTextEqualsExample + { + // + private static readonly byte[] s_nameUtf8 = Encoding.UTF8.GetBytes("name"); + // + public static void Run(ReadOnlySpan jsonReadOnlySpan) + { + int count = 0; + int total = 0; + var reader = new Utf8JsonReader(jsonReadOnlySpan); + + // + while (reader.Read()) + { + JsonTokenType tokenType = reader.TokenType; + + switch (tokenType) + { + case JsonTokenType.StartObject: + total++; + break; + case JsonTokenType.PropertyName: + if (reader.ValueTextEquals(s_nameUtf8)) + { + count++; + } + break; + } + // + } + Console.WriteLine($"{count} out of {total} have \"name\" properties"); + } + } +} diff --git a/snippets/core/system-text-json/csharp/WeatherForecast.cs b/snippets/core/system-text-json/csharp/WeatherForecast.cs index 335a399fce3..4d143a3aa0e 100644 --- a/snippets/core/system-text-json/csharp/WeatherForecast.cs +++ b/snippets/core/system-text-json/csharp/WeatherForecast.cs @@ -13,6 +13,26 @@ public class WeatherForecast } // + // + public class WeatherForecastWithPrevious + { + public DateTimeOffset Date { get; set; } + public int TemperatureCelsius { get; set; } + public string Summary { get; set; } + public WeatherForecast PreviousForecast { get; set; } + } + // + + // + public class WeatherForecastWithPreviousAsObject + { + public DateTimeOffset Date { get; set; } + public int TemperatureCelsius { get; set; } + public string Summary { get; set; } + public object PreviousForecast { get; set; } + } + // + // public class WeatherForecastWithLong { @@ -306,6 +326,30 @@ public static WeatherForecast CreateWeatherForecast() return weatherForecast; } + public static WeatherForecastWithPrevious CreateWeatherForecastWithPrevious() + { + var weatherForecast = new WeatherForecastWithPrevious + { + Date = DateTime.Parse("2019-08-01"), + TemperatureCelsius = 25, + Summary = "Hot", + PreviousForecast = CreateWeatherForecastDerived() + }; + return weatherForecast; + } + + public static WeatherForecastWithPreviousAsObject CreateWeatherForecastWithPreviousAsObject() + { + var weatherForecast = new WeatherForecastWithPreviousAsObject + { + Date = DateTime.Parse("2019-08-01"), + TemperatureCelsius = 25, + Summary = "Hot", + PreviousForecast = CreateWeatherForecastDerived() + }; + return weatherForecast; + } + public static WeatherForecastWithLong CreateWeatherForecastWithLong() { var weatherForecast = new WeatherForecastWithLong