Skip to content

System.Text.Json 9 Serialization Issue rg. Flags-Enums when using JsonStringEnumConverter #114770

@incowia-dke

Description

@incowia-dke

Description

In comparison to previous library versions, flags enums are serialized differently in some cases when JsonStringEnumConverter is used. In particular constellations the textual identifiers are completely missing in the resulting json string.

The problematic constellations occur, if there are combinations of bits, in addition to the "pure" options. If a bit-combination is used where not all bits have also an explicit value, no useful text is returned at all, but the numeric representation of the combined bits instead.

Reproduction Steps

If the following code targets .NET8, the test works fine. If .NET9 is targeted (or System.Text.Json 9.0.x is referenced explicitly) the test fails. Please see comments in the source code for details. We tried the new [JsonStringEnumMemberName]-Attribute, but that didn't help either.

using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonSerializationTests
{
    [Flags]
    public enum MyEnum1
    {
        UNKNOWN = 0,
        BIT0    = 1,
        BIT1    = 2,
        BIT2    = 4,
        BIT3    = 8,
        BITS01  = 3,
    }

    [Flags]
    public enum MyEnum2
    {
        UNKNOWN = 0,
        BIT0    = 1,
        // direct option for bit 1 missing
        BIT2    = 4,
        BIT3    = 8,
        BITS01  = 3,
    }

    [TestClass]
    public sealed class Test1
    {
        [TestMethod]
        public void FlagsEnumTest()
        {
            JsonSerializerOptions options = new()
            {
                WriteIndented = false,
                Converters    = { new JsonStringEnumConverter() }
            };

            var e1 = MyEnum1.BITS01 | MyEnum1.BIT3;
            string json1 = JsonSerializer.Serialize ( e1, options );
            // .NET8 => "BITS01, BIT3"
            // .NET9 => "BIT0, BIT1, BIT3" (which is not so bad, although different from .NET8)

            var e2 = MyEnum2.BITS01 | MyEnum2.BIT3;
            string json2 = JsonSerializer.Serialize ( e2, options );
            // .NET8 => "BITS01, BIT3"
            // .NET9 => "11"; // that's the problematic behaviour

            Assert.IsTrue ( json1.Contains("BITS01") && json1.Contains("BIT3"), "json 1 failed" );
            Assert.IsTrue ( json2.Contains("BITS01") && json2.Contains("BIT3"), "json 2 failed" );
        }
    }
}

Expected behavior

The behaviour should not change in comparison to previous library versions.

Actual behavior

The serialization behaves differently as of library version 9, as described above.

Regression?

was ok before library version 9

Known Workarounds

possibly a custom converter replacing the built-in JsonStringEnumConverter

Configuration

System.Text.Json 9.0.x (tested including 9.0.4)

Other information

No response

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions