Skip to content

Commit 572993c

Browse files
Remove JsonSerializerOptions copy in ProblemDetailsJsonOptionsSetup (#46716)
* Remove JsonSerializerOptions copy in ProblemDetailsJsonOptionsSetup * Adding comments * Update src/Http/Http.Extensions/test/ProblemDetailsServiceCollectionExtensionsTest.cs Co-authored-by: Brennan <[email protected]> --------- Co-authored-by: Brennan <[email protected]>
1 parent 5dd9e93 commit 572993c

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

src/Http/Http.Extensions/src/ProblemDetailsJsonOptionsSetup.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,23 @@ internal sealed class ProblemDetailsJsonOptionsSetup : IPostConfigureOptions<Jso
1111
{
1212
public void PostConfigure(string? name, JsonOptions options)
1313
{
14-
if (options.SerializerOptions.TypeInfoResolver is not null)
14+
switch (options.SerializerOptions.TypeInfoResolver)
1515
{
16-
if (options.SerializerOptions.IsReadOnly)
17-
{
18-
options.SerializerOptions = new(options.SerializerOptions);
19-
}
20-
21-
// Combine the current resolver with our internal problem details context
22-
options.SerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine(options.SerializerOptions.TypeInfoResolver!, ProblemDetailsJsonContext.Default);
16+
case DefaultJsonTypeInfoResolver:
17+
// In this case, the current configuration is using a reflection-based resolver
18+
// and we are prepending our internal problem details context to be evaluated
19+
// first.
20+
options.SerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine(ProblemDetailsJsonContext.Default, options.SerializerOptions.TypeInfoResolver);
21+
break;
22+
case not null:
23+
// Combine the current resolver with our internal problem details context (adding last)
24+
options.SerializerOptions.AddContext<ProblemDetailsJsonContext>();
25+
break;
26+
default:
27+
// Not adding our source gen context when TypeInfoResolver == null
28+
// since adding it will skip the reflection-based resolver and potentially
29+
// cause unexpected serialization problems
30+
break;
2331
}
2432
}
2533
}

src/Http/Http.Extensions/test/ProblemDetailsServiceCollectionExtensionsTest.cs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Text.Json.Serialization;
5+
using System.Text.Json.Serialization.Metadata;
56
using Microsoft.AspNetCore.Http.Json;
67
using Microsoft.AspNetCore.Mvc;
78
using Microsoft.Extensions.DependencyInjection;
@@ -103,7 +104,7 @@ public void AddProblemDetails_CombinesProblemDetailsContext()
103104
}
104105

105106
[Fact]
106-
public void AddProblemDetails_CombinesProblemDetailsContext_ForReadOnlyJsonOptions()
107+
public void AddProblemDetails_Throws_ForReadOnlyJsonOptions()
107108
{
108109
// Arrange
109110
var collection = new ServiceCollection();
@@ -120,10 +121,7 @@ public void AddProblemDetails_CombinesProblemDetailsContext_ForReadOnlyJsonOptio
120121
var services = collection.BuildServiceProvider();
121122
var jsonOptions = services.GetService<IOptions<JsonOptions>>();
122123

123-
Assert.NotNull(jsonOptions.Value);
124-
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver);
125-
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver.GetTypeInfo(typeof(ProblemDetails), jsonOptions.Value.SerializerOptions));
126-
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver.GetTypeInfo(typeof(TypeA), jsonOptions.Value.SerializerOptions));
124+
Assert.Throws<InvalidOperationException>(() => jsonOptions.Value);
127125
}
128126

129127
[Fact]
@@ -166,6 +164,28 @@ public void AddProblemDetails_DoesNotCombineProblemDetailsContext_WhenNullTypeIn
166164
Assert.Null(jsonOptions.Value.SerializerOptions.TypeInfoResolver);
167165
}
168166

167+
[Fact]
168+
public void AddProblemDetails_CombineProblemDetailsContext_WhenDefaultTypeInfoResolver()
169+
{
170+
// Arrange
171+
var collection = new ServiceCollection();
172+
collection.AddOptions<JsonOptions>();
173+
collection.ConfigureAll<JsonOptions>(options => options.SerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver());
174+
175+
// Act
176+
collection.AddProblemDetails();
177+
178+
// Assert
179+
var services = collection.BuildServiceProvider();
180+
var jsonOptions = services.GetService<IOptions<JsonOptions>>();
181+
182+
Assert.NotNull(jsonOptions.Value);
183+
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver);
184+
Assert.IsNotType<DefaultJsonTypeInfoResolver>(jsonOptions.Value.SerializerOptions.TypeInfoResolver);
185+
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver.GetTypeInfo(typeof(ProblemDetails), jsonOptions.Value.SerializerOptions));
186+
Assert.NotNull(jsonOptions.Value.SerializerOptions.TypeInfoResolver.GetTypeInfo(typeof(TypeA), jsonOptions.Value.SerializerOptions));
187+
}
188+
169189
[JsonSerializable(typeof(TypeA))]
170190
internal partial class TestExtensionsJsonContext : JsonSerializerContext
171191
{ }

0 commit comments

Comments
 (0)