Skip to content

Serialize enum as string: net10.0, ConfigureHttpJsonOptions, DataContractJsonSerializer and source-generation samples - #2160

Merged
vladimir-pecanac-main merged 2 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/67044-enum-to-string
Aug 31, 2026
Merged

Serialize enum as string: net10.0, ConfigureHttpJsonOptions, DataContractJsonSerializer and source-generation samples#2160
vladimir-pecanac-main merged 2 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/67044-enum-to-string

Conversation

@vladimir-pecanac-main

Copy link
Copy Markdown
Collaborator

Refresh of json-csharp/JsonSerializationOfEnumAsString, the sample behind How to Serialize Enum to a String in C#, which has not been touched since 2022.

Target framework and packages

All seven projects move from net6.0 (out of support) to net10.0. Package versions were read from NuGet today, not from memory: Newtonsoft.Json 13.0.4, Microsoft.AspNetCore.Mvc.NewtonsoftJson 10.0.11, Microsoft.AspNetCore.Mvc.Testing 10.0.11, Microsoft.NET.Test.Sdk 18.9.0, xunit 2.9.3, xunit.runner.visualstudio 3.1.5, coverlet.collector 10.0.1. The runner stays on the 3.x line because 4.0.0 is the xUnit v3 line and this folder is on xUnit v2. The System.Text.Json package references are gone: the library is in-box on net10.0.

Sample code

  • Minimal API: builder.Services.Configure<JsonOptions>(...) becomes builder.Services.ConfigureHttpJsonOptions(...). Both configure the same Microsoft.AspNetCore.Http.Json.JsonOptions object; the extension is the current way to reach it, and it drops the using Microsoft.AspNetCore.Http.Json; directive.
  • Both Web API samples called app.UseAuthorization() with no authentication or authorization registered anywhere in the solution. Removed.

New tests

  • [JsonStringEnumMemberName] (.NET 9+): with a registered JsonStringEnumConverter the custom string is emitted, and without one the same model still writes a number. The attribute does nothing on its own, which is the trap worth covering.
  • DataContractJsonSerializer: enums are always written as numbers, [EnumMember] is ignored, reading the string form back throws a SerializationException, a number no member defines is accepted, and the XML DataContractSerializer does honour [EnumMember] on the very same type. The class is in-box on net10.0 and needs no package reference.
  • Source-generated serialization through a JsonSerializerContext with UseStringEnumConverter = true, the AOT-safe form the IL3050 analyzer points at.

The existing test asserting that System.Text.Json ignores [EnumMember] is kept unchanged: that behaviour is still current on .NET 10 and the article states it.

dotnet build -c Release: 0 errors, 0 warnings. dotnet test -c Release: 27 passed, 0 failed (SDK 10.0.302, runtime 10.0.10).

… DataContractJsonSerializer and source-generation samples

Retarget all seven projects from net6.0 to net10.0 and refresh packages
against NuGet: Newtonsoft.Json 13.0.4, Microsoft.AspNetCore.Mvc.NewtonsoftJson
10.0.11, Microsoft.AspNetCore.Mvc.Testing 10.0.11, Microsoft.NET.Test.Sdk
18.9.0, xunit 2.9.3, xunit.runner.visualstudio 3.1.5 (the v2-compatible line),
coverlet.collector 10.0.1. The System.Text.Json package references are dropped
because the library is in-box on net10.0.

Minimal API sample now uses ConfigureHttpJsonOptions instead of
Configure<JsonOptions>; both are the same Microsoft.AspNetCore.Http.Json.JsonOptions
object, and the extension is the first-class way to reach it. Dead
app.UseAuthorization() removed from both Web API samples: neither registers
authentication or authorization.

New coverage:
- JsonStringEnumMemberName, both with a registered JsonStringEnumConverter
  (custom string) and without one (still a number).
- DataContractJsonSerializer: enums are always written as numbers,
  EnumMember is ignored, reading the string form back throws, an undefined
  number is accepted, and the XML DataContractSerializer does honour
  EnumMember on the same type.
- Source-generated serialization through a JsonSerializerContext with
  UseStringEnumConverter set.

Build clean with 0 warnings, 27 tests passing on SDK 10.0.302.
@vladimir-pecanac-main
vladimir-pecanac-main merged commit 2fab44e into CodeMazeBlog:main Aug 31, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant