Description of the bug
We tag enums with [JsonConverter(typeof(JsonStringEnumConverter))] to get them stringified on serialization to JSON. While this does work as intended, it seems that the JsonStringEnumConverter doesn't automatically correct or invalidate integers on deserialization. Its default setting is to allow int values.
Here are the operations that use JsonStringEnumConverter for deserializing request data:
POST .../verification/verify (AddressType)
POST .../verification/send (AddressType)
PUT .../users/current/profilesettings (Language)
PATCH .../users/current/profilesettings (Language)
Steps To Reproduce
In any of the API operations listed above, pass an integer value to JSON fields that internally maps to enum.
Expected behavior: 400 Bad data as response
Actual behavior: successful response or internal server error because the integer was treated as valid input
Solution considerations
Current codebase state
We currently have two groups of enums in the codebase:
Group 1 — enums that already serialize as string
Language, AddressType (verification), VerificationType, ProfileType
Group 2 — currently serialized as integers:
UserType (UserType.cs) has no attribute and explicit numeric values 0–6. It's serialized in UserProfile.UserType (UserProfile.cs:59), which is returned by all the GET user endpoints, the internal lookup, contact-point lookups, etc. Today consumers get "userType": 1.
PartyTypeName (third-party contract, from Altinn.Register.Contracts), also in UserProfile, also serializes as an integer today ("partyTypeName": 1)
Key questions to consider:
1. what should be the default for a new enum?
- Serialize to int when converting C# -> JSON, and accept int values when deserializing from JSON -> C# request model
vs
- Serialize to string when converting C# -> JSON, and reject int values when deserializing from JSON -> C# request model
2. Where do we want to define the enum behavior?
Description of the bug
We tag enums with
[JsonConverter(typeof(JsonStringEnumConverter))]to get them stringified on serialization to JSON. While this does work as intended, it seems that the JsonStringEnumConverter doesn't automatically correct or invalidate integers on deserialization. Its default setting is to allow int values.Here are the operations that use JsonStringEnumConverter for deserializing request data:
POST .../verification/verify (AddressType)
POST .../verification/send (AddressType)
PUT .../users/current/profilesettings (Language)
PATCH .../users/current/profilesettings (Language)
Steps To Reproduce
In any of the API operations listed above, pass an integer value to JSON fields that internally maps to enum.
Expected behavior: 400 Bad data as response
Actual behavior: successful response or internal server error because the integer was treated as valid input
Solution considerations
Current codebase state
We currently have two groups of enums in the codebase:
Group 1 — enums that already serialize as string
Language,AddressType(verification),VerificationType,ProfileTypeGroup 2 — currently serialized as integers:
UserType(UserType.cs) has no attribute and explicit numeric values 0–6. It's serialized in UserProfile.UserType (UserProfile.cs:59), which is returned by all the GET user endpoints, the internal lookup, contact-point lookups, etc. Today consumers get"userType": 1.PartyTypeName(third-party contract, fromAltinn.Register.Contracts), also in UserProfile, also serializes as an integer today ("partyTypeName": 1)Key questions to consider:
1. what should be the default for a new enum?
vs
2. Where do we want to define the enum behavior?
vs