Skip to content

Commit

Permalink
Add special serialization handling for nullable ValueTuples
Browse files Browse the repository at this point in the history
This commit adds special serialization handling for nullable ValueTuples.
Specialized handling is required as without, a nullable ValueTuple type
ends up falling into CustomDyanmicObjectResolver inside of
NestFormatterResolver, which will build a dynamic formatter using
MetaType et.al, which enumerates interfaces and can cause a
CLR error when calling `at System.Runtime.CompilerServices.ITuple.get_Length()`.

Fixes #4703
  • Loading branch information
russcam committed May 26, 2020
1 parent 61386f3 commit 8972392
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
39 changes: 39 additions & 0 deletions src/Elasticsearch.Net/Utf8Json/Resolvers/DynamicGenericResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,45 @@ internal static object GetFormatter(Type t)

return CreateInstance(tupleFormatterType, ti.GenericTypeArguments);
}

// Nullable ValueTuple
else if (isNullable && nullableElementType.GetTypeInfo().IsConstructedGenericType() &&
nullableElementType.GetTypeInfo().FullName.StartsWith("System.ValueTuple"))
{
Type tupleFormatterType = null;
switch (nullableElementType.GenericTypeArguments.Length)
{
case 1:
tupleFormatterType = typeof(ValueTupleFormatter<>);
break;
case 2:
tupleFormatterType = typeof(ValueTupleFormatter<,>);
break;
case 3:
tupleFormatterType = typeof(ValueTupleFormatter<,,>);
break;
case 4:
tupleFormatterType = typeof(ValueTupleFormatter<,,,>);
break;
case 5:
tupleFormatterType = typeof(ValueTupleFormatter<,,,,>);
break;
case 6:
tupleFormatterType = typeof(ValueTupleFormatter<,,,,,>);
break;
case 7:
tupleFormatterType = typeof(ValueTupleFormatter<,,,,,,>);
break;
case 8:
tupleFormatterType = typeof(ValueTupleFormatter<,,,,,,,>);
break;
default:
break;
}

var tupleFormatter = CreateInstance(tupleFormatterType, nullableElementType.GenericTypeArguments);
return CreateInstance(typeof(StaticNullableFormatter<>), new [] { nullableElementType }, tupleFormatter);
}
#endif

// ArraySegement
Expand Down
2 changes: 1 addition & 1 deletion tests/Tests.Reproduce/GithubIssue4703.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void NullableValueTupleDoesNotThrow()
var response = a.Subject;

var json = Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);
json.Should().Be(@"{""tupleNullable"":{""item1"":""somestring"",""item2"":42}}");
json.Should().Be(@"{""tupleNullable"":{""Item1"":""somestring"",""Item2"":42}}");
}
}

Expand Down

0 comments on commit 8972392

Please sign in to comment.