New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JsonNumberEnumConverter writes string property names #102120
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis |
This is the default serialization behavior of enum types when serialized as dictionary keys, consider var value = new Dictionary<TestEnum, TestEnum> { [TestEnum.FirstValue] = TestEnum.FirstValue };
var output = JsonSerializer.Serialize(value);
Console.WriteLine(output); // {"FirstValue":0}
public enum TestEnum
{
FirstValue = 0,
SecondValue = 1
} The Arguably this behavior is surprising, but at the same time it's shipped behavior so changing it today would count as a breaking change. As a workaround you might consider authoring a custom converter type while also overriding the |
Kind of figured that changing it outright would be a breaking change; I was curious if adopting a new parameter to configure this behavior specifically was out of the question, however if the recommendation is to make a custom converter, I suppose that's the route we'll take (and, even if this were changed, it'd be an issue for multi-targeting projects like the one I linked, bwah). And by the custom converter, I suppose you mean a converter specifically for the enum type that implements the aforementioned method? Or was that meant to be interpreted as a dictionary converter (like the one I linked), thanks! |
Yep 👍 |
Description
Right now, when using System.Text.Json, adding a
JsonNumberEnumConverter
to the converter list, the resulting JSON when serializing a dictionary is that the enum is written as a string value with the enum's name instead of the string representation of the value of the enum.Reproduction Steps
Add the JsonNumberEnumConverter to the serializer options, and serialize an object.
Expected behavior
STJ writes a sting-ified integer as the dictionary key, resulting in the following JSON:
{"0":{}}
Actual behavior
The enum name is written for the key instead:
{"FirstValue":{}}
Regression?
No response
Known Workarounds
Writing a custom converter for dictionaries that writes the enum values as string integers is the route we've gone for now:
https://github.com/Remora/Remora.Discord/blob/e1ae7617c587fcce41d350c43c00b194797743df/Backend/Remora.Discord.API/Json/Converters/Internal/EnumIntKeyDictionaryConverterFactory.cs#L114-L124
Though this relies on having a key converter which can turn the enum into a string key, as well as converting the whole dictionary, which can make it cumbersome to work with.
Configuration
.NET 8.0.100
Linux Mint 21.3 x86_64
Platform agnostic
Other information
This is likely a very niche issue (I couldn't find any other issue referencing this behavior being problematic.
The converter does appear to have logic supporting writing values as integer keys, however this only appears to be if the value written falls out of range of the enum itself:
runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs
Lines 329 to 336 in 7ce5d0f
I'd also like to note that this is only an issue because of Discord, whom is using the same enum for both arrays and dictionaries.
From their documentation, using a dictionary for
integration_types_config
: https://discord.com/developers/docs/resources/application#edit-current-applicationAnd an array for
integration_types
: https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structureBoth of these use the
ApplicationIntegrationType
enum, but one is serialized as integers[0, 1]
and the other as string representations of those values{"0": { ... } }
The text was updated successfully, but these errors were encountered: