// First, walk up the class hierarchy for any supported types.
for (Type? candidate = typeInfo.Type.BaseType; candidate != null; candidate = candidate.BaseType)
{
- JsonTypeInfo? candidateInfo = typeInfo.Options.GetTypeInfoInternal(candidate, ensureNotNull: null);
+ JsonTypeInfo? candidateInfo = ResolveAncestorTypeInfo(candidate, typeInfo.Options);
if (candidateInfo?.PolymorphismOptions != null)
{
// stop on the first ancestor that has a match
// Now, walk the interface hierarchy for any polymorphic interface declarations.
foreach (Type interfaceType in typeInfo.Type.GetInterfaces())
{
- JsonTypeInfo? candidateInfo = typeInfo.Options.GetTypeInfoInternal(interfaceType, ensureNotNull: null);
+ JsonTypeInfo? candidateInfo = ResolveAncestorTypeInfo(interfaceType, typeInfo.Options);
if (candidateInfo?.PolymorphismOptions != null)
{
if (matchingResult != null)
}
return matchingResult;
+
+ static JsonTypeInfo? ResolveAncestorTypeInfo(Type type, JsonSerializerOptions options)
+ {
+ try
+ {
+ return options.GetTypeInfoInternal(type, ensureNotNull: null);
+ }
+ catch
+ {
+ // The resolver produced an exception when resolving the ancestor type.
+ // Eat the exception and report no result instead.
+ return null;
+ }
+ }
}
/// <summary>
Assert.Equal(Expected, json);
}
+ [Fact]
+ public async Task CustomResolverWithFailingAncestorType_DoesNotSurfaceException()
+ {
+ var options = new JsonSerializerOptions
+ {
+ TypeInfoResolver = new DefaultJsonTypeInfoResolver
+ {
+ Modifiers =
+ {
+ static typeInfo =>
+ {
+ if (typeInfo.Type == typeof(MyThing) ||
+ typeInfo.Type == typeof(IList))
+ {
+ throw new InvalidOperationException("some latent custom resolution bug");
+ }
+ }
+ }
+ }
+ };
+
+ object value = new MyDerivedThing { Number = 42 };
+ string json = await Serializer.SerializeWrapper(value, options);
+ Assert.Equal("""{"Number":42}""", json);
+
+ value = new int[] { 1, 2, 3 };
+ json = await Serializer.SerializeWrapper(value, options);
+ Assert.Equal("[1,2,3]", json);
+ }
+
class MyClass
{
public string Value { get; set; }
public int Number { get; set; }
}
+ class MyDerivedThing : MyThing
+ {
+ }
+
class MyThingCollection : List<IThing> { }
class MyThingDictionary : Dictionary<string, IThing> { }