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

Enum decorated with [JsonStringEnumMemberName] fails to deserialize #106406

Closed
martincostello opened this issue Aug 14, 2024 · 7 comments
Closed

Comments

@martincostello
Copy link
Member

Description

I saw [JsonStringEnumMemberName] in the API diff for .NET 9 preview 7 and thought I'd try it out as I have a custom converter to deal with SCREAMING_SNAKE_CASE at the moment in an application, so it should simplify things.

On updating the code however, one of my tests fails due to deserialization failing.

I can't see an obvious reason why - the test case contains the value "USER_INITIATED", which matches the code.

Reproduction Steps

  1. Clone martincostello/alexa-london-travel@8ab652f
  2. Run build.ps1 in the root of the repository.

Expected behavior

The tests pass and enum values are correctly (de)serialized.

Actual behavior

An exception is thrown by the Can_Deserialize_Request test:

  LondonTravel.Skill.Tests test failed with 1 error(s) and 1 warning(s) (11.7s)
    C:\Coding\martincostello\alexa-london-travel\test\LondonTravel.Skill.Tests\SerializationTests.cs(25): error TESTERROR:
      Can_Deserialize_Request(name: "SessionEndedRequest", expectedType: typeof(MartinCostello.LondonTravel.Skill.Models.SessionEndedRequest)) (84ms): Error Message: Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException : Error converting the Lambda event JSON payload to type MartinCostello.LondonTravel.Skill.Models.SkillRequest: The JSON value could not be converted to MartinCostello.LondonTravel.
      Skill.Models.Reason. Path: $.request.reason | LineNumber: 23 | BytePositionInLine: 30.
      ---- System.Text.Json.JsonException : The JSON value could not be converted to MartinCostello.LondonTravel.Skill.Models.Reason. Path: $.request.reason | LineNumber: 23 | BytePositionInLine: 30.
      Stack Trace:
         at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Deserialize[T](Stream requestStream)
         at MartinCostello.LondonTravel.Skill.SerializationTests.Can_Deserialize_Request(String name, Type expectedType) in C:\Coding\martincostello\alexa-london-travel\test\LondonTravel.Skill.Tests\SerializationTests.cs:line 25
         at InvokeStub_SerializationTests.Can_Deserialize_Request(Object, Span`1)
         at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
      ----- Inner Stack Trace -----
         at System.Text.Json.ThrowHelper.ThrowJsonException(String message)
         at System.Text.Json.Serialization.Converters.EnumConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
         at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
         at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
         at System.Text.Json.Serialization.JsonConverter`1.OnTryReadAsObject(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, Object& value)
         at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
         at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
         at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
         at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
         at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
         at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
         at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Utf8JsonReader& reader, ReadStack& state)
         at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
         at System.Text.Json.JsonSerializer.Deserialize[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo)
         at Amazon.Lambda.Serialization.SystemTextJson.SourceGeneratorLambdaJsonSerializer`1.InternalDeserialize[T](Byte[] utf8Json)
         at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Deserialize[T](Stream requestStream)

Regression?

No - new functionality.

Known Workarounds

None.

Configuration

  • .NET SDK 9.0.100-preview.7.24407.12
  • System.Text.Json 9.0.0-preview.7.24405.7

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 Aug 14, 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.

@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Aug 14, 2024

Thanks. Any chance you could distil this to a minimal repro? 🙏

@martincostello
Copy link
Member Author

I'll give it a whirl tomorrow. This was a very end-of-day I'll just give this a quick try...oh no kinda thing.

@Ilchert
Copy link

Ilchert commented Aug 14, 2024

Hello @martincostello according to the example #74385 you need to add JsonConverter(typeof(JsonStringEnumConverter)) attribute to your enum.

@martincostello
Copy link
Member Author

@Ilchert Thanks, that was it.

I'd incorrectly assumed I didn't need it anymore and completely removed my converter attribute, rather than just change it to not use my custom converter.

@martincostello martincostello closed this as not planned Won't fix, can't repro, duplicate, stale Aug 14, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Aug 14, 2024
@eiriktsarpalis
Copy link
Member

Would it make sense to infer the string-based converter based on the presence of the new attribute? I'm not sure what the right approach should be here.

@martincostello
Copy link
Member Author

That would certainly help guide people towards the pit of success.

I hadn't seen any specific documentation or example of using the new attribute, I just saw the API diff adding entry and thought "oh I know where I could use that" and got over-agressive with the deleting forgetting the default behaviour would have been to treat it as an int.

@github-actions github-actions bot locked and limited conversation to collaborators Sep 14, 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

3 participants