Skip to content
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

Overriding global serialization options with JsonConverterAttribute behaves unexpectedly #102712

Closed
azygis opened this issue May 27, 2024 · 3 comments

Comments

@azygis
Copy link

azygis commented May 27, 2024

Description

It seems like applying the [JsonConverter(typeof(JsonNumberEnumConverter<TEnum>))] on the enum level does not override the global serializer options. Based on my own understanding (and then later a confirmation in this comment) the attribute allows falling back to number serialization in case the global options specifies a default of string serialization.

In my case, I don't want to serialize flags to string as that makes it harder to handle flags in the frontend. Added the attribute on the enum type itself and started plucking my hair out since that wouldn't work no matter what. Then added the attribute on the property instead and voila, then it works.

Reproduction contains a NUnit test which covers both working and not working cases.

Reproduction Steps

[TestCase(typeof(RecordOne))]
[TestCase(typeof(RecordTwo))]
public void JsonSerializerOptions_RespectsConverterType(Type recordType)
{
    // ARRANGE
    var options = new JsonSerializerOptions();
    options.Converters.Add(new JsonStringEnumConverter());

    var record = Activator.CreateInstance(recordType, [Enum.One]);

    // ACT
    var result = JsonSerializer.Serialize(record, options);

    // ASSERT
    Assert.That(result, Is.EqualTo("{\"EnumValue\":1}"));
}

public sealed record RecordOne(Enum EnumValue);

public sealed record RecordTwo([property: JsonConverter(typeof(JsonNumberEnumConverter<Enum>))] Enum EnumValue);

[JsonConverter(typeof(JsonNumberEnumConverter<Enum>))]
public enum Enum { One = 1 }

Expected behavior

Converter specified on type level overrides the global converter settings.

Actual behavior

Converter specified on type level does not override the global converter settings.

Regression?

No response

Known Workarounds

No response

Configuration

.NET version: 8.0.204
OS: Ubuntu 23.10

I do not think OS has any impact, to be honest.

Other information

No response

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label May 27, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

@elgonzo
Copy link

elgonzo commented May 27, 2024

The observed behavior is intentional and documented. From the JsonConverterAttribute documentation (https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonconverterattribute):

When placed on a type, the specified converter will be used unless a compatible converter is added to the JsonSerializerOptions.Converters collection or there is another JsonConverterAttribute on a property of the same type.


Additionally, it seems to me the comment (or thread) you linked to doesn't seem to discuss nor refer to applying a JsonConverterAttribute to a type...

@azygis
Copy link
Author

azygis commented May 27, 2024

Damn, looked in the wrong direction.

Yeah, the linked comment is not exactly about the attribute on a type, but about the fact that JsonNumberEnumConverter allows overriding default serialization specified by default. I was under impression it would override on type level as well, but I see that's not the case and understand it's intentional. That's a bit tedious, but it is what it is.

Thanks.

@azygis azygis closed this as completed May 27, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label May 27, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jun 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants