diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs index fd6f38ada0db7a..5d1c3afe69dd60 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Runtime.ExceptionServices; namespace System.Text.Json.Serialization.Metadata { @@ -33,7 +34,16 @@ public ReflectionMemberAccessor() : null; } - return () => ctorInfo.Invoke(null); + return () => +#if NET + ctorInfo.Invoke( + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: null, + culture: null); +#else + ctorInfo.Invoke(null); +#endif } public override Func CreateParameterizedConstructor(ConstructorInfo constructor) @@ -56,6 +66,13 @@ public override Func CreateParameterizedConstructor(ConstructorI argsToPass[i] = arguments[i]; } +#if NET + return (T)constructor.Invoke( + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: argsToPass, + culture: null); +#else try { return (T)constructor.Invoke(argsToPass); @@ -67,6 +84,7 @@ public override Func CreateParameterizedConstructor(ConstructorI // This doesn't apply to the method below as it supports a max of 4 constructor params. throw e.InnerException ?? e; } +#endif }; } @@ -108,7 +126,16 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate { +#if NET + return (T)constructor.Invoke( + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: new object?[] { value }, + culture: null); +#else try { return (T)constructor.Invoke(new object?[] { value }); @@ -130,6 +164,7 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate CreatePropertyGetter(Property return delegate (object obj) { - return (TProperty)getMethodInfo.Invoke(obj, null)!; +#if NET + return (TProperty)getMethodInfo.Invoke( + obj, + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: null, + culture: null)!; +#else + try + { + return (TProperty)getMethodInfo.Invoke(obj, null)!; + } + catch (TargetInvocationException e) when (e.InnerException is not null) + { + ExceptionDispatchInfo.Capture(e.InnerException).Throw(); + throw; // unreachable + } +#endif }; } @@ -177,7 +239,24 @@ public override Func CreatePropertyGetter CreatePropertySetter(Proper return delegate (object obj, TProperty value) { - setMethodInfo.Invoke(obj, new object[] { value! }); +#if NET + setMethodInfo.Invoke( + obj, + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: new object[] { value! }, + culture: null); +#else + try + { + setMethodInfo.Invoke(obj, new object[] { value! }); + } + catch (TargetInvocationException e) when (e.InnerException is not null) + { + ExceptionDispatchInfo.Capture(e.InnerException).Throw(); + } +#endif }; } @@ -216,10 +311,27 @@ public override UnionTryGetValueAccessor CreateUnionTryGetValueAccessor< { KeyValuePair entry = entries[i]; caseTypes[i] = entry.Key; - chain[i] = (UnionTryGetValueAccessor)typeof(ReflectionMemberAccessor) + object? accessor = typeof(ReflectionMemberAccessor) .GetMethod(nameof(CreateUnionTryGetValueAccessorCore), BindingFlags.NonPublic | BindingFlags.Static)! .MakeGenericMethod(typeof(TUnion), entry.Key) - .Invoke(null, new object[] { entry.Value })!; +#if NET + .Invoke( + null, + BindingFlags.DoNotWrapExceptions, + binder: null, + parameters: new object[] { entry.Value }, + culture: null); +#else + .Invoke(null, new object[] { entry.Value }); +#endif + + if (accessor is null) + { + throw new InvalidOperationException( + $"Failed to create union accessor for type '{entry.Key}' using method '{entry.Value}'."); + } + + chain[i] = (UnionTryGetValueAccessor)accessor; } return (TUnion union, out Type? caseType, out object? value) =>