graphql-client
graphql-client copied to clipboard
PascalCase and camelCase enum values fail to deserialize
Both PascalCase and camelCase enum values fail to deserialize using the default (ConstantCaseEnumConverter) serializers.
The GraphQL.Client.Serializer.Tests project tests serialization using the SerializeToStringTestData class. However, an equivalent deserialization test is not included. For the type
public enum TestEnum { Regular, PascalCase, camelCase, lower, UPPER, CONSTANT_CASE } (taken from the SerializeToStringTestData class), Regular, lower, UPPER, and CONSTANT_CASE deserialize correctly. However, both PascalCase and camelCase do not deserialize. Instead a null value is returned. In the case of a subscription message, it fails silently and the message is simply swallowed (see #312).
I have verified this by adding a new test case to the DeserializeResponseTestData. This includes:
yield return new object[]
{
"{\"data\":{\"testEnums\":{\"enums\":[\"REGULAR\",\"PASCAL_CASE\",\"CAMEL_CASE\",\"LOWER\",\"UPPER\",\"CONSTANT_CASE\"]}}}",
new GraphQLResponse<TestEnumsResponse>
{
Data = new TestEnumsResponse
{
TestEnums = new TestEnums
{
Enums = new List<SerializeToStringTestData.TestEnum>(Enum
.GetValues(typeof(SerializeToStringTestData.TestEnum))
.Cast<SerializeToStringTestData.TestEnum>())
}
}
}
};
and
public class TestEnumsResponse
{
public TestEnums TestEnums { get; set; }
}
public class TestEnums
{
public List<SerializeToStringTestData.TestEnum> Enums { get; set; }
}
This occurs for both NewtonSoft and SystemText JSON providers.
I am able to work around this issue by subclassing ConstantCaseEnumConverter and implementing my own ReadJson method, which gets the text, removes underbars, and then tries to parse, otherwise delegating to the base class.
if (reader.TokenType == JsonToken.String)
{
string? enumText = reader.Value?.ToString();
enumText = enumText.Replace("_", "");
if (Enum.TryParse(objectType, enumText, true, out var enumVal))
return enumVal;
return base.ReadJson(reader, objectType, existingValue, serializer);
}
I don't like this workaround, but in my case it works for the moment.
This is using 3.2.0 under .net5, but I believe the problem has existed for a few years.