From b368f4d7d5e44aaa77691320cec4656e2ff66093 Mon Sep 17 00:00:00 2001 From: Vladimir Pecanac Date: Sun, 30 Aug 2026 18:22:59 +0200 Subject: [PATCH] CamelCase serialization: retarget net10.0, cache the options instance, add the web preset - Both projects net7.0 -> net10.0. - Test packages to current stable: Microsoft.NET.Test.Sdk 18.9.0, xunit 2.9.3, xunit.runner.visualstudio 4.0.0, coverlet.collector 10.0.1. - JsonSerializerExtensions now holds one static readonly JsonSerializerOptions instead of building a fresh instance per call, and DeserializeFromCamelCase returns T? (Deserialize can return null; the old signature raised CS8603). - Program.cs demonstrates new JsonSerializerOptions(JsonSerializerDefaults.Web), the preset ASP.NET Core applies, with a covering test. - ExtensionTests: xUnit assertion arguments were reversed (Assert.Equal(actual, expected)); swapped to (expected, actual) and used Assert.True for the boolean. --- .../CamelCaseSerialization.csproj | 2 +- .../JsonSerializerExtensions.cs | 21 +++++------- .../CamelCaseSerialization/Program.cs | 6 +++- .../CamelCaseSerialization.Tests.csproj | 10 +++--- .../ExtensionTests.cs | 32 +++++++++++++++---- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/CamelCaseSerialization.csproj b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/CamelCaseSerialization.csproj index 2b14c8172d..cd19a35631 100644 --- a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/CamelCaseSerialization.csproj +++ b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/CamelCaseSerialization.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net10.0 enable enable diff --git a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/JsonSerializerExtensions.cs b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/JsonSerializerExtensions.cs index 1f9f76aa85..74db967aea 100644 --- a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/JsonSerializerExtensions.cs +++ b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/JsonSerializerExtensions.cs @@ -4,19 +4,14 @@ namespace CamelCaseSerialization; public static class JsonSerializerExtensions { - public static string SerializeWithCamelCase(this T data) + private static readonly JsonSerializerOptions CamelCaseOptions = new() { - return JsonSerializer.Serialize(data, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }); - } + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; - public static T DeserializeFromCamelCase(this string json) - { - return JsonSerializer.Deserialize(json, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }); - } + public static string SerializeWithCamelCase(this T data) => + JsonSerializer.Serialize(data, CamelCaseOptions); + + public static T? DeserializeFromCamelCase(this string json) => + JsonSerializer.Deserialize(json, CamelCaseOptions); } diff --git a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/Program.cs b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/Program.cs index 7e41e86009..0abc7ec71c 100644 --- a/json-csharp/CamelCaseSerialization/CamelCaseSerialization/Program.cs +++ b/json-csharp/CamelCaseSerialization/CamelCaseSerialization/Program.cs @@ -32,8 +32,12 @@ PropertyNamingPolicy = JsonNamingPolicy.CamelCase })}"); +// With the JsonSerializerDefaults.Web preset, the same options ASP.NET Core applies +var webOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); +Console.WriteLine($"{JsonSerializer.Serialize(person, webOptions)}"); + // With extension method Console.WriteLine($"{person.SerializeWithCamelCase()}"); var personObject = personString.DeserializeFromCamelCase(); -Console.WriteLine($"{personObject.FirstName} {personObject.Surname}({personObject.IsActive}) is {personObject.Age}"); +Console.WriteLine($"{personObject?.FirstName} {personObject?.Surname}({personObject?.IsActive}) is {personObject?.Age}"); diff --git a/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/CamelCaseSerialization.Tests.csproj b/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/CamelCaseSerialization.Tests.csproj index b7a7bbb0ac..544a60a0ad 100644 --- a/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/CamelCaseSerialization.Tests.csproj +++ b/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/CamelCaseSerialization.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 diff --git a/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/ExtensionTests.cs b/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/ExtensionTests.cs index 5d85868649..4fc97c92de 100644 --- a/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/ExtensionTests.cs +++ b/json-csharp/CamelCaseSerialization/Tests/CamelCaseSerialization.Tests/ExtensionTests.cs @@ -1,3 +1,5 @@ +using System.Text.Json; + namespace CamelCaseSerialization.Tests; public class ExtensionTests @@ -15,7 +17,7 @@ public void GivenPerson_WhenUsingExtensionMethod_ThenSerializeWithCamelCase() var result = person.SerializeWithCamelCase(); - Assert.Equal(result, """{"firstName":"John","surname":"Doe","age":20,"isActive":true}"""); + Assert.Equal("""{"firstName":"John","surname":"Doe","age":20,"isActive":true}""", result); } [Fact] @@ -24,10 +26,28 @@ public void GivenJsonStringInCamelCase_WhenUsingExtensionMethod_ThenDeserializeI var personJson = """{"firstName":"John","surname":"Doe","age":20,"isActive":true}"""; var result = personJson.DeserializeFromCamelCase(); - - Assert.Equal(result.Age, 20); - Assert.Equal(result.FirstName, "John"); - Assert.Equal(result.Surname, "Doe"); - Assert.Equal(result.IsActive, true); + + Assert.NotNull(result); + Assert.Equal(20, result.Age); + Assert.Equal("John", result.FirstName); + Assert.Equal("Doe", result.Surname); + Assert.True(result.IsActive); + } + + [Fact] + public void GivenPerson_WhenSerializingWithWebDefaults_ThenPropertyNamesAreCamelCase() + { + var person = new Person + { + Age = 20, + FirstName = "John", + Surname = "Doe", + IsActive = true + }; + var webOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); + + var result = JsonSerializer.Serialize(person, webOptions); + + Assert.Equal("""{"firstName":"John","surname":"Doe","age":20,"isActive":true}""", result); } }