From 20d50b4b7b8a0867ec3cdf08aaac3353318695a7 Mon Sep 17 00:00:00 2001 From: Vladimir Pecanac Date: Sun, 30 Aug 2026 18:45:03 +0200 Subject: [PATCH] Serialize a list to JSON: retarget net10.0, add stream serialization - Both projects net7.0 -> net10.0 (net7.0 is out of support). - Packages: BenchmarkDotNet 0.15.8, Newtonsoft.Json 13.0.4, Microsoft.NET.Test.Sdk 18.9.0, xunit 2.9.3, xunit.runner.visualstudio 4.0.0, coverlet.collector 10.0.1. - New SerializeToStreamAsync(Stream) on the System.Text.Json class, writing straight to the destination with JsonSerializer.SerializeAsync, plus a test asserting the stream contents. - Club.NumberOfPlayers is now an int. It held "26" as a string, so every JSON sample showed a quoted number in an article about JSON typing. Test expectations updated to match. - Primary constructors on both serializer classes; Program.cs to top-level statements. Build clean, 5/5 tests pass on SDK 10.0.302. --- .../HowToSerializeAListToJsonInCSharp/Club.cs | 2 +- .../GenerateBenchmarkData.cs | 2 +- .../HowToSerializeAListToJsonInCSharp.csproj | 6 ++--- .../Program.cs | 12 ++------- .../SerializeListToJsonWithNewtonsoftJson.cs | 12 +++------ .../SerializeListToJsonWithSystemTextJson.cs | 23 ++++++++-------- .../Tests/NewtonsoftJsonMethodsTests.cs | 12 ++++----- .../Tests/SystemTextJsonMethodsTests.cs | 26 ++++++++++++++----- .../Tests/Tests.csproj | 10 +++---- 9 files changed, 51 insertions(+), 54 deletions(-) diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Club.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Club.cs index db4852d7b3..40866ccbf3 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Club.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Club.cs @@ -5,6 +5,6 @@ public class Club public string Name { get; set; } = string.Empty; public int YearFounded { get; set; } public string Country { get; set; } = string.Empty; - public string NumberOfPlayers { get; set; } = string.Empty; + public int NumberOfPlayers { get; set; } } } \ No newline at end of file diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/GenerateBenchmarkData.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/GenerateBenchmarkData.cs index a5be52aa39..7b12895a4f 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/GenerateBenchmarkData.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/GenerateBenchmarkData.cs @@ -12,7 +12,7 @@ public static List Generate10000ListsForBenchmark() Name = $"Club-{i}", YearFounded = 1000 + i, Country = "England", - NumberOfPlayers = "30", + NumberOfPlayers = 30, }; englishClubs.Add(club); } diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp.csproj b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp.csproj index 9abe53f151..91a63decb6 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp.csproj +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp.csproj @@ -2,14 +2,14 @@ Exe - net7.0 + net10.0 enable enable - - + + diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Program.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Program.cs index 0443a9d56a..fa35ed76bc 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Program.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/Program.cs @@ -1,12 +1,4 @@ using BenchmarkDotNet.Running; +using HowToSerializeAListToJsonInCSharp; -namespace HowToSerializeAListToJsonInCSharp -{ - internal class Program - { - static void Main(string[] args) - { - BenchmarkRunner.Run(); - } - } -} \ No newline at end of file +BenchmarkRunner.Run(); \ No newline at end of file diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithNewtonsoftJson.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithNewtonsoftJson.cs index b2f7a098e4..a4b26fbe19 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithNewtonsoftJson.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithNewtonsoftJson.cs @@ -4,9 +4,8 @@ namespace HowToSerializeAListToJsonInCSharp { - public class SerializeListToJsonWithNewtonsoftJson + public class SerializeListToJsonWithNewtonsoftJson(List clubList) { - private readonly List _clubList; private readonly JsonSerializerSettings _settings = new() { @@ -14,14 +13,9 @@ private readonly JsonSerializerSettings _settings ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, }; - public SerializeListToJsonWithNewtonsoftJson(List clubList) - { - _clubList = clubList; - } - public string SerializeObjectMethod() { - return JsonConvert.SerializeObject(_clubList, _settings); + return JsonConvert.SerializeObject(clubList, _settings); } public string JsonSerializerClass() @@ -30,7 +24,7 @@ public string JsonSerializerClass() var stringBuilder = new StringBuilder(); using (var writer = new JsonTextWriter(new StringWriter(stringBuilder))) { - serializer.Serialize(writer, _clubList); + serializer.Serialize(writer, clubList); } return stringBuilder.ToString(); diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithSystemTextJson.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithSystemTextJson.cs index 1495f0851e..206bfc769a 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithSystemTextJson.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/HowToSerializeAListToJsonInCSharp/SerializeListToJsonWithSystemTextJson.cs @@ -2,31 +2,30 @@ namespace HowToSerializeAListToJsonInCSharp { - public class SerializeListToJsonWithSystemTextJson + public class SerializeListToJsonWithSystemTextJson(List clubList) { - private readonly List _clubList; - private readonly JsonSerializerOptions _options - = new() + private readonly JsonSerializerOptions _options + = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true, }; - public SerializeListToJsonWithSystemTextJson(List clubList) - { - _clubList = clubList; - } - public string SerializeMethod() { - return JsonSerializer.Serialize(_clubList, _options); + return JsonSerializer.Serialize(clubList, _options); } public string SerializeToUtf8BytesMethod() { - var result = JsonSerializer.SerializeToUtf8Bytes(_clubList, _options); - + var result = JsonSerializer.SerializeToUtf8Bytes(clubList, _options); + return System.Text.Encoding.UTF8.GetString(result); } + + public async Task SerializeToStreamAsync(Stream stream) + { + await JsonSerializer.SerializeAsync(stream, clubList, _options); + } } } \ No newline at end of file diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/NewtonsoftJsonMethodsTests.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/NewtonsoftJsonMethodsTests.cs index d6ab97d717..8ec834c0de 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/NewtonsoftJsonMethodsTests.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/NewtonsoftJsonMethodsTests.cs @@ -11,21 +11,21 @@ public class NewtonsoftJsonMethodsTests Name = "Arsenal", YearFounded = 1886, Country = "England", - NumberOfPlayers = "26", + NumberOfPlayers = 26, }, new Club { Name = "Manchester City", YearFounded = 1880, Country = "England", - NumberOfPlayers = "25", + NumberOfPlayers = 25, }, new Club { Name = "Sunderland", YearFounded = 1879, Country = "England", - NumberOfPlayers = "30", + NumberOfPlayers = 30, } }; @@ -39,19 +39,19 @@ private readonly string _expectedResult "name": "Arsenal", "yearFounded": 1886, "country": "England", - "numberOfPlayers": "26" + "numberOfPlayers": 26 }, { "name": "Manchester City", "yearFounded": 1880, "country": "England", - "numberOfPlayers": "25" + "numberOfPlayers": 25 }, { "name": "Sunderland", "yearFounded": 1879, "country": "England", - "numberOfPlayers": "30" + "numberOfPlayers": 30 } ] """; diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/SystemTextJsonMethodsTests.cs b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/SystemTextJsonMethodsTests.cs index bb30bd60a1..27f67ad5bb 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/SystemTextJsonMethodsTests.cs +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/SystemTextJsonMethodsTests.cs @@ -1,4 +1,5 @@ -using HowToSerializeAListToJsonInCSharp; +using System.Text; +using HowToSerializeAListToJsonInCSharp; namespace Tests { @@ -11,21 +12,21 @@ public class SystemTextJsonMethodsTests Name = "Arsenal", YearFounded = 1886, Country = "England", - NumberOfPlayers = "26", + NumberOfPlayers = 26, }, new Club { Name = "Manchester City", YearFounded = 1880, Country = "England", - NumberOfPlayers = "25", + NumberOfPlayers = 25, }, new Club { Name = "Sunderland", YearFounded = 1879, Country = "England", - NumberOfPlayers = "30", + NumberOfPlayers = 30, } }; @@ -39,19 +40,19 @@ private readonly string _expectedResult "name": "Arsenal", "yearFounded": 1886, "country": "England", - "numberOfPlayers": "26" + "numberOfPlayers": 26 }, { "name": "Manchester City", "yearFounded": 1880, "country": "England", - "numberOfPlayers": "25" + "numberOfPlayers": 25 }, { "name": "Sunderland", "yearFounded": 1879, "country": "England", - "numberOfPlayers": "30" + "numberOfPlayers": 30 } ] """; @@ -71,5 +72,16 @@ public void GivenAList_WhenUsingTheSerializeToUtf8BytesMethod_ThenReturnsAJsonSt Assert.Equal(_expectedResult, englishClubsJson); } + + [Fact] + public async Task GivenAList_WhenUsingTheSerializeToStreamAsyncMethod_ThenWritesAJsonStringToTheStream() + { + using var stream = new MemoryStream(); + + await _serializeList.SerializeToStreamAsync(stream); + + var englishClubsJson = Encoding.UTF8.GetString(stream.ToArray()); + Assert.Equal(_expectedResult, englishClubsJson); + } } } \ No newline at end of file diff --git a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/Tests.csproj b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/Tests.csproj index 732723d701..7c33fc6ce2 100644 --- a/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/Tests.csproj +++ b/json-csharp/HowToSerializeAListToJsonInCSharp/Tests/Tests.csproj @@ -1,7 +1,7 @@ - net7.0 + net10.0 enable enable @@ -9,13 +9,13 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all