From 4a1cf5f4736b6ff8d7de46fc6076b2e976ec287f Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 22 Feb 2026 19:36:37 +0800 Subject: [PATCH 1/2] Reject non-generic collections and add tests Resolve #24914 --- .../Abp/ObjectMapping/ObjectMappingHelper.cs | 7 ++ .../ObjectMappingHelper_Tests.cs | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 framework/test/Volo.Abp.ObjectMapping.Tests/Volo/Abp/ObjectMapping/ObjectMappingHelper_Tests.cs diff --git a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs index 5949edaba9..f73b65b306 100644 --- a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs +++ b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs @@ -59,6 +59,13 @@ public static class ObjectMappingHelper supportedCollectionTypes.Contains(type.GetGenericTypeDefinition()) || type.GetInterfaces().Any(i => i.IsGenericType && supportedCollectionTypes.Contains(i.GetGenericTypeDefinition()))) { + if (!type.IsGenericType) + { + elementType = null!; + definitionGenericType = null!; + return false; + } + elementType = type.GetGenericArguments()[0]; definitionGenericType = type.GetGenericTypeDefinition(); if (definitionGenericType == typeof(IEnumerable<>) || diff --git a/framework/test/Volo.Abp.ObjectMapping.Tests/Volo/Abp/ObjectMapping/ObjectMappingHelper_Tests.cs b/framework/test/Volo.Abp.ObjectMapping.Tests/Volo/Abp/ObjectMapping/ObjectMappingHelper_Tests.cs new file mode 100644 index 0000000000..c262dad81a --- /dev/null +++ b/framework/test/Volo.Abp.ObjectMapping.Tests/Volo/Abp/ObjectMapping/ObjectMappingHelper_Tests.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Shouldly; +using Xunit; + +namespace Volo.Abp.ObjectMapping; + +public class ObjectMappingHelper_Tests +{ + [Fact] + public void IsCollectionGenericType_Should_Return_True_For_Standard_GenericCollection() + { + var result = ObjectMappingHelper.IsCollectionGenericType, List>( + out var sourceArg, out var destArg, out var defGenericType); + + result.ShouldBeTrue(); + sourceArg.ShouldBe(typeof(MappingTestSource)); + destArg.ShouldBe(typeof(MappingTestDestination)); + defGenericType.ShouldBe(typeof(List<>)); + } + + [Fact] + public void IsCollectionGenericType_Should_Return_True_For_Array() + { + var result = ObjectMappingHelper.IsCollectionGenericType( + out var sourceArg, out var destArg, out _); + + result.ShouldBeTrue(); + sourceArg.ShouldBe(typeof(MappingTestSource)); + destArg.ShouldBe(typeof(MappingTestDestination)); + } + + [Fact] + public void IsCollectionGenericType_Should_Normalize_IEnumerable_To_List() + { + var result = ObjectMappingHelper.IsCollectionGenericType, IEnumerable>( + out _, out _, out var defGenericType); + + result.ShouldBeTrue(); + defGenericType.ShouldBe(typeof(List<>)); + } + + [Fact] + public void IsCollectionGenericType_Should_Normalize_ICollection_To_Collection() + { + var result = ObjectMappingHelper.IsCollectionGenericType, ICollection>( + out _, out _, out var defGenericType); + + result.ShouldBeTrue(); + defGenericType.ShouldBe(typeof(Collection<>)); + } + + [Fact] + public void IsCollectionGenericType_Should_Return_False_For_NonCollection() + { + var result = ObjectMappingHelper.IsCollectionGenericType( + out _, out _, out _); + + result.ShouldBeFalse(); + } + + [Fact] + public void IsCollectionGenericType_Should_Return_False_For_NonGeneric_DerivedCollection() + { + var result = ObjectMappingHelper.IsCollectionGenericType, MappingTestDestinationList>( + out _, out _, out _); + + result.ShouldBeFalse(); + } +} + +public class MappingTestSource +{ + public string Value { get; set; } = ""; +} + +public class MappingTestDestination +{ + public string Value { get; set; } = ""; +} + +public class MappingTestDestinationList : List +{ +} From ee47706de64bf1bf9acc5ab48ed99942b6de1638 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 22 Feb 2026 19:47:53 +0800 Subject: [PATCH 2/2] Refactor condition in IsCollectionGenericTypeInternal for clarity --- .../Volo/Abp/ObjectMapping/ObjectMappingHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs index f73b65b306..3bc1a1389b 100644 --- a/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs +++ b/framework/src/Volo.Abp.ObjectMapping/Volo/Abp/ObjectMapping/ObjectMappingHelper.cs @@ -55,8 +55,8 @@ public static class ObjectMappingHelper return true; } - if (type.IsGenericType && - supportedCollectionTypes.Contains(type.GetGenericTypeDefinition()) || + if ((type.IsGenericType && + supportedCollectionTypes.Contains(type.GetGenericTypeDefinition())) || type.GetInterfaces().Any(i => i.IsGenericType && supportedCollectionTypes.Contains(i.GetGenericTypeDefinition()))) { if (!type.IsGenericType)