diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index fd190452e294f8..1fd5cf78a15505 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -92,6 +92,7 @@ private sealed class Parser private readonly Type? _jsonValueType; // Unsupported types + private readonly Type _delegateType; private readonly Type _typeType; private readonly Type _serializationInfoType; private readonly Type _intPtrType; @@ -219,6 +220,7 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene _jsonValueType = _metadataLoadContext.Resolve(JsonValueFullName); // Unsupported types. + _delegateType = _metadataLoadContext.Resolve(SpecialType.System_Delegate); _typeType = _metadataLoadContext.Resolve(typeof(Type)); _serializationInfoType = _metadataLoadContext.Resolve(typeof(Runtime.Serialization.SerializationInfo)); _intPtrType = _metadataLoadContext.Resolve(typeof(IntPtr)); @@ -901,7 +903,8 @@ private TypeGenerationSpec GetOrAddTypeGenerationSpec(Type type, JsonSourceGener } } else if (_knownUnsupportedTypes.Contains(type) || - ImplementsIAsyncEnumerableInterface(type)) + ImplementsIAsyncEnumerableInterface(type) || + _delegateType.IsAssignableFrom(type)) { classType = ClassType.KnownUnsupportedType; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs index fdc632d96d2f6c..f211939119505b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UnsupportedTypeConverterFactory.cs @@ -23,6 +23,8 @@ public override bool CanConvert(Type type) type == typeof(SerializationInfo) || type == typeof(IntPtr) || type == typeof(UIntPtr) || + // Exlude delegates. + typeof(Delegate).IsAssignableFrom(type) || // DateOnly/TimeOnly support to be added in future releases; // guard against invalid object-based serializations for now. // cf. https://github.com/dotnet/runtime/issues/53539 diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs index a41380e3e60d9c..8c0f57b422a55d 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs @@ -2817,5 +2817,37 @@ public class TypeWith_IgnoredPropWith_BadConverter public class BadConverter { } + + [Fact] + public async Task TestClassWithIgnoredCallbacks() + { + Assert.Equal("{}", await JsonSerializerWrapperForString.SerializeWrapper(new ClassWithIgnoredCallbacks())); + var obj = await JsonSerializerWrapperForString.DeserializeWrapper(@"{""Func"":"""",""Action"":""""}"); + Assert.False(obj.Func("")); + Assert.Null(obj.Action); + } + + [Fact] + public async Task TestClassWithCallbacks() + { + await Assert.ThrowsAsync(async () => await JsonSerializerWrapperForString.SerializeWrapper(new ClassWithCallbacks())); + await Assert.ThrowsAsync(async () => await JsonSerializerWrapperForString.DeserializeWrapper(@"{""Func"":{},""Action"":{}")); + } + + public class ClassWithIgnoredCallbacks + { + [JsonIgnore] + public Func Func { get; set; } = (val) => false; + + [JsonIgnore] + public Action Action { get; set; } + } + + public class ClassWithCallbacks + { + public Func Func { get; set; } + + public Action Action { get; set; } = (val) => Console.WriteLine(); + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs index 3b38cefe23e98c..a698165e3f9677 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs @@ -268,6 +268,8 @@ public override async Task HonorJsonPropertyName_PrivateSetter() [JsonSerializable(typeof(TypeWith_IgnoredRefStringProp))] [JsonSerializable(typeof(TypeWith_PropWith_BadConverter))] [JsonSerializable(typeof(TypeWith_IgnoredPropWith_BadConverter))] + [JsonSerializable(typeof(ClassWithIgnoredCallbacks))] + [JsonSerializable(typeof(ClassWithCallbacks))] internal sealed partial class PropertyVisibilityTestsContext_Metadata : JsonSerializerContext { } @@ -439,6 +441,8 @@ public override async Task JsonIgnoreCondition_WhenWritingNull_OnValueType_Fail_ [JsonSerializable(typeof(TypeWith_IgnoredRefStringProp))] [JsonSerializable(typeof(TypeWith_PropWith_BadConverter))] [JsonSerializable(typeof(TypeWith_IgnoredPropWith_BadConverter))] + [JsonSerializable(typeof(ClassWithIgnoredCallbacks))] + [JsonSerializable(typeof(ClassWithCallbacks))] internal sealed partial class PropertyVisibilityTestsContext_Default : JsonSerializerContext { }