-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
System.Text.Json: Using JsonStringEnumConverter, after changing CurrentCulture to "sv-SE", enums with unknown negative values serialize strangely, and cannot be deserialized. #68600
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescriptionJSON serialization should not depend on the current locale in any way, but enum serialization is affected by the current setting for More specifically, I serialized an enum to JSON using
When I attempted to deserialize the value, an exception was thrown, making it impossible to round-trip the enum value in the Swedish locale:
Demo fiddle here: https://dotnetfiddle.net/Lztx97 Reproduction Steps
Expected behaviorJSON serialization of enums should be completely independent of locale. Actual behaviorJSON serialization of negative integer-valued enums breaks if Regression?No response Known WorkaroundsNo response ConfigurationEnvironment version: .NET 6.0.0-rtm.21522.10 (6.0.0) Other informationThe problem seems to be here, in
The converter caches the current negative sign on startup, but it that changes the value will become stale.
|
If I'm understanding this correctly, would changing |
Unfortunately not. The problem is that, while
I.e.
Is going to return with a localized minus sign. In fact there doesn't seem to be a method to generate a culture-invariant string representation of an enum, see https://dotnetfiddle.net/JNQv52 which tries all of the following and gets a localized minus sign for each:
Rather unfortunately actually. You may need to eliminated the cached
at runtime whenever the converter needs to know the current minus sign used by I'm guessing the author of
Replacing
Might be sufficient to solve the problem. Of course, there might be some private Enum API that returns an invariant version of |
I agree with your analysis, I think we should take the fix you are proposing. Looking up the negative sign from the current culture every time might theoretically incur a performance hit, but it should only impact numeric values when the string enum converter is enabled -- hardly in the hot path for enum serialization. |
Wait, I'm looking at the solution and it seems like current culture is always used in serialization? This makes no sense to me - I would expect the opposite. For example, in web apps when you're serializing or deserializing stuff for JSON, you don't care what language the website uses, it shouldn't depend on the culture at all because serialization should be using a standard format that everyone can agree on. But given that this does use current culture by default, there should at the very least be a way to opt out of that, and specify that serialization/deserialization should use the invariant culture, without using the global invariant culture flag, because you still want current culture for other things where it's appropriate. |
Does JSON even allow using other characters than the standard |
True, but as @dbc2 originally pointed out enums don't appear to have a culture-insensitive formatting method. The change appears to predate the open sourcing of .NET, @stephentoub might know we've obsoleted the method or why the obsolete method isn't using the |
Description
JSON serialization should not depend on the current locale in any way, but enum serialization is affected by the current setting for
CurrentInfo.NumberFormatInfo.NegativeSign
such that that enums with negative unknown values cannot be round-tripped. This seems wrong.More specifically, I serialized an enum to JSON using
JsonStringEnumConverter
withallowIntegerValues : true
with the current locale being the invariant locale. Afterwards, I changedCultureInfo.CurrentCulture
to Swedish, which happens to use the character U+2212 as its negative sign. I then serialized a unknown negative value of the same enum type to JSON, and it was serialized strangely, as follows:When I attempted to deserialize the value, an exception was thrown, making it impossible to round-trip the enum value in the Swedish locale:
Demo fiddle here: https://dotnetfiddle.net/Lztx97
Reproduction Steps
Expected behavior
JSON serialization of enums should be completely independent of locale.
Actual behavior
JSON serialization of negative integer-valued enums breaks if
NumberFormatInfo.CurrentInfo.NegativeSign
is changed.Regression?
No response
Known Workarounds
No response
Configuration
Environment version: .NET 6.0.0-rtm.21522.10 (6.0.0)
System.Text.Json version: System.Text.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
Other information
The problem seems to be here, in
EnumConverter.cs
:The converter caches the current negative sign on startup, but if that changes the value will become stale.
The text was updated successfully, but these errors were encountered: