From 814c1012f1e4f9157b2e15c201c139eda48c8605 Mon Sep 17 00:00:00 2001 From: desjoerd Date: Mon, 2 Dec 2024 17:34:44 +0100 Subject: [PATCH] Fix TypeMapper UseReference not used when mapping a GenericType --- .../Generation/TypeMapperTests.cs | 43 +++++++++++++++++++ .../Generation/JsonTypeDescription.cs | 7 +++ 2 files changed, 50 insertions(+) diff --git a/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs b/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs index 56a4e936d..af93dd26a 100644 --- a/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs +++ b/src/NJsonSchema.Tests/Generation/TypeMapperTests.cs @@ -124,5 +124,48 @@ public async Task When_generic_type_mapper_is_defined_then_it_is_called_and_the_ Assert.False(schema.Definitions.ContainsKey("MyWrapperOfMyBar")); } + public class MyStringFoo + { + public MyWrapper PropertyString { get; set; } + + public MyWrapper PropertyMyBar { get; set; } + } + + public class WithoutReferenceTypeMapper : ITypeMapper + { + public Type MappedType => typeof(MyWrapper<>); + + public bool UseReference => false; + + public void GenerateSchema(JsonSchema schema, TypeMapperContext context) + { + context.JsonSchemaGenerator.Generate(schema, context.Type.GenericTypeArguments[0], context.JsonSchemaResolver); + } + } + + + [Fact] + public async Task When_generic_type_mapper_is_defined_then_it_is_called_and_the_use_reference_false_is_used() + { + // Act + var schema = NewtonsoftJsonSchemaGenerator.FromType(new NewtonsoftJsonSchemaGeneratorSettings + { + TypeMappers = + { + new WithoutReferenceTypeMapper() + } + }); + + // Assert + var json = schema.ToJson(); + Assert.False(schema.Definitions.ContainsKey("string")); + Assert.False(schema.Definitions.ContainsKey("MyWrapperOfString")); + Assert.True(schema.Definitions.ContainsKey("MyBar")); + + Assert.Contains("$ref", json); // The $ref to MyBar should be present + // There should only be one $ref, which is to Bar, this is the case when the first and last index of "$ref" is the same + Assert.True(json.IndexOf("$ref", StringComparison.Ordinal) == json.LastIndexOf("$ref", StringComparison.Ordinal)); + } + } } diff --git a/src/NJsonSchema/Generation/JsonTypeDescription.cs b/src/NJsonSchema/Generation/JsonTypeDescription.cs index 5cd0b3dc3..a8180919b 100644 --- a/src/NJsonSchema/Generation/JsonTypeDescription.cs +++ b/src/NJsonSchema/Generation/JsonTypeDescription.cs @@ -6,6 +6,7 @@ // Rico Suter, mail@rsuter.com //----------------------------------------------------------------------- +using System.Reflection; using Namotion.Reflection; using NJsonSchema.Generation.TypeMappers; @@ -91,6 +92,12 @@ public static JsonTypeDescription CreateForEnumeration(ContextualType type, Json public bool RequiresSchemaReference(IEnumerable typeMappers) { var typeMapper = typeMappers.FirstOrDefault(m => m.MappedType == ContextualType.OriginalType); + if (typeMapper == null && ContextualType.OriginalType.GetTypeInfo().IsGenericType) + { + var genericType = ContextualType.OriginalType.GetGenericTypeDefinition(); + typeMapper = typeMappers.FirstOrDefault(m => m.MappedType == genericType); + } + if (typeMapper != null) { return typeMapper.UseReference;