Skip to content

Commit a96c91f

Browse files
committed
fix minimal api json options not being respected
1 parent 5e2e6fc commit a96c91f

7 files changed

+71
-28
lines changed

src/Swashbuckle.AspNetCore.SwaggerGen/DependencyInjection/SwaggerGenServiceCollectionExtensions.cs

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,30 @@ public static IServiceCollection AddSwaggerGen(
4444
return services;
4545
}
4646

47+
#if NET
48+
public static IServiceCollection AddSwaggerGenMinimalApisJsonOptions(this IServiceCollection services)
49+
{
50+
return services.Replace(
51+
ServiceDescriptor.Transient<ISerializerDataContractResolver>((s) =>
52+
{
53+
var options = s.GetRequiredService<IOptionsSnapshot<AspNetCore.Http.Json.JsonOptions>>().Value.SerializerOptions;
54+
55+
return new JsonSerializerDataContractResolver(options);
56+
}));
57+
}
58+
59+
public static IServiceCollection AddSwaggerGenMvcJsonOptions(this IServiceCollection services)
60+
{
61+
return services.Replace(
62+
ServiceDescriptor.Transient<ISerializerDataContractResolver>((s) =>
63+
{
64+
var options = s.GetRequiredService<IOptionsSnapshot<AspNetCore.Mvc.JsonOptions>>().Value.JsonSerializerOptions;
65+
66+
return new JsonSerializerDataContractResolver(options);
67+
}));
68+
}
69+
#endif
70+
4771
public static void ConfigureSwaggerGen(
4872
this IServiceCollection services,
4973
Action<SwaggerGenOptions> setupAction)
@@ -70,21 +94,40 @@ private JsonSerializerOptions ResolveOptions()
7094
JsonSerializerOptions serializerOptions;
7195

7296
/*
73-
* First try to get the options configured for MVC,
74-
* then try to get the options configured for Minimal APIs if available,
75-
* then try the default JsonSerializerOptions if available,
76-
* otherwise create a new instance as a last resort as this is an expensive operation.
97+
* There is no surefire way to do this.
98+
* However, both JsonOptions are defaulted in the same way.
99+
* If neither is configured it makes no difference which one is chosen.
100+
* If both are configured, then we just need to make a choice.
101+
* As Minimal APIs are newer if someone is configuring them
102+
* it's probably more likely that is what they're using.
103+
*
104+
* If either JsonOptions is null we will try to create a new instance as
105+
* a last resort as this is an expensive operation.
77106
*/
78107
#if NET
79108
serializerOptions =
80-
_serviceProvider.GetService<IOptions<AspNetCore.Mvc.JsonOptions>>()?.Value?.JsonSerializerOptions
81-
?? _serviceProvider.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions
109+
_serviceProvider.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions
82110
?? JsonSerializerOptions.Default;
111+
112+
if (HasConfiguredMinimalApiJsonOptions())
113+
{
114+
serializerOptions ??= _serviceProvider.GetService<IOptions<AspNetCore.Http.Json.JsonOptions>>()?.Value?.SerializerOptions;
115+
}
83116
#else
84117
serializerOptions = new JsonSerializerOptions();
85118
#endif
86119

87120
return serializerOptions;
88121
}
122+
123+
#if NET
124+
private bool HasConfiguredMinimalApiJsonOptions()
125+
{
126+
if (_serviceProvider.GetService<IEnumerable<IConfigureOptions<AspNetCore.Http.Json.JsonOptions>>>().Any())
127+
return true;
128+
129+
return _serviceProvider.GetService<IEnumerable<IPostConfigureOptions<AspNetCore.Http.Json.JsonOptions>>>().Any();
130+
}
131+
#endif
89132
}
90133
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json) -> Microsoft.OpenApi.Any.IOpenApiAny
1+
static Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.AddSwaggerGenMinimalApisJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection
2+
static Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.AddSwaggerGenMvcJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection
3+
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json) -> Microsoft.OpenApi.Any.IOpenApiAny
24
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json, System.Text.Json.JsonSerializerOptions options) -> Microsoft.OpenApi.Any.IOpenApiAny
35
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiSchemaExtensions.ResolveType(this Microsoft.OpenApi.Models.OpenApiSchema schema, Swashbuckle.AspNetCore.SwaggerGen.SchemaRepository schemaRepository) -> string
46
Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json) -> Microsoft.OpenApi.Any.IOpenApiAny
1+
static Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.AddSwaggerGenMinimalApisJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection
2+
static Microsoft.Extensions.DependencyInjection.SwaggerGenServiceCollectionExtensions.AddSwaggerGenMvcJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection
3+
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json) -> Microsoft.OpenApi.Any.IOpenApiAny
24
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory.CreateFromJson(string json, System.Text.Json.JsonSerializerOptions options) -> Microsoft.OpenApi.Any.IOpenApiAny
35
static Swashbuckle.AspNetCore.SwaggerGen.OpenApiSchemaExtensions.ResolveType(this Microsoft.OpenApi.Models.OpenApiSchema schema, Swashbuckle.AspNetCore.SwaggerGen.SchemaRepository schemaRepository) -> string
46
Swashbuckle.AspNetCore.SwaggerGen.OpenApiAnyFactory

test/Swashbuckle.AspNetCore.IntegrationTests/snapshots/VerifyTests.Swagger_IsValidJson_No_Startup_entryPointType=WebApi.Program_swaggerRequestUri=v1.DotNet8_0.verified.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -988,12 +988,11 @@
988988
},
989989
"DateTimeKind": {
990990
"enum": [
991-
0,
992-
1,
993-
2
991+
"Unspecified",
992+
"Utc",
993+
"Local"
994994
],
995-
"type": "integer",
996-
"format": "int32"
995+
"type": "string"
997996
},
998997
"Fruit": {
999998
"type": "object",

test/Swashbuckle.AspNetCore.IntegrationTests/snapshots/VerifyTests.Swagger_IsValidJson_No_Startup_entryPointType=WebApi.Program_swaggerRequestUri=v1.DotNet9_0.verified.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -988,12 +988,11 @@
988988
},
989989
"DateTimeKind": {
990990
"enum": [
991-
0,
992-
1,
993-
2
991+
"Unspecified",
992+
"Utc",
993+
"Local"
994994
],
995-
"type": "integer",
996-
"format": "int32"
995+
"type": "string"
997996
},
998997
"Fruit": {
999998
"type": "object",

test/Swashbuckle.AspNetCore.IntegrationTests/snapshots/VerifyTests.TypesAreRenderedCorrectly.DotNet8_0.verified.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -988,12 +988,11 @@
988988
},
989989
"DateTimeKind": {
990990
"enum": [
991-
0,
992-
1,
993-
2
991+
"Unspecified",
992+
"Utc",
993+
"Local"
994994
],
995-
"type": "integer",
996-
"format": "int32"
995+
"type": "string"
997996
},
998997
"Fruit": {
999998
"type": "object",

test/Swashbuckle.AspNetCore.IntegrationTests/snapshots/VerifyTests.TypesAreRenderedCorrectly.DotNet9_0.verified.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -988,12 +988,11 @@
988988
},
989989
"DateTimeKind": {
990990
"enum": [
991-
0,
992-
1,
993-
2
991+
"Unspecified",
992+
"Utc",
993+
"Local"
994994
],
995-
"type": "integer",
996-
"format": "int32"
995+
"type": "string"
997996
},
998997
"Fruit": {
999998
"type": "object",

0 commit comments

Comments
 (0)