Skip to content

Commit 48747e3

Browse files
HaikAsatryanclaude
andcommitted
Restore OpenAPI 3.1 and fix numeric schemas rendered as string union
Microsoft.AspNetCore.OpenApi reflects JsonNumberHandling.AllowReadingFromString (default under JsonSerializerDefaults.Web) by emitting numeric schemas as type: ["integer","string"] with a bigint regex. Swagger UI rendered ints/decimals as strings in bodies and broke query/path params; downgrading to 3.0 dropped the type entirely with the same symptom. Add NumericStringUnionTransformer to strip the string alternative and the regex, leaving pure integer/number. Switch OpenApiVersion back to 3.1. Workaround for dotnet/aspnetcore#58882 and #64145. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c01debc commit 48747e3

3 files changed

Lines changed: 78 additions & 3 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using Microsoft.AspNetCore.OpenApi;
2+
using Microsoft.OpenApi;
3+
4+
namespace SharedKernel.OpenApi;
5+
6+
// Workaround for https://github.com/dotnet/aspnetcore/issues/58882 and #64145.
7+
// Microsoft.AspNetCore.OpenApi reflects JsonNumberHandling.AllowReadingFromString
8+
// (enabled by default via JsonSerializerDefaults.Web) by emitting numeric schemas as
9+
// type: ["integer","string"] with a bigint regex pattern. Swagger UI renders this as a
10+
// string in bodies and breaks query/path parameters; downgrading to OpenAPI 3.0 drops
11+
// the type entirely. We strip the string alternative so numbers stay numbers in the doc.
12+
// Runtime deserialization is unchanged: STJ still accepts quoted numbers if a client sends them.
13+
internal sealed class NumericStringUnionTransformer : IOpenApiSchemaTransformer
14+
{
15+
public Task TransformAsync(OpenApiSchema schema,
16+
OpenApiSchemaTransformerContext context,
17+
CancellationToken cancellationToken)
18+
{
19+
Strip(schema);
20+
return Task.CompletedTask;
21+
}
22+
23+
private static void Strip(IOpenApiSchema? schema)
24+
{
25+
if (schema is not OpenApiSchema s)
26+
{
27+
return;
28+
}
29+
30+
if (s.Type is { } t
31+
&& (t & JsonSchemaType.String) != 0
32+
&& (t & (JsonSchemaType.Integer | JsonSchemaType.Number)) != 0)
33+
{
34+
s.Type = t & ~JsonSchemaType.String;
35+
s.Pattern = null;
36+
}
37+
38+
if (s.Properties is not null)
39+
{
40+
foreach (var p in s.Properties.Values)
41+
{
42+
Strip(p);
43+
}
44+
}
45+
46+
Strip(s.Items);
47+
Strip(s.AdditionalProperties);
48+
Strip(s.Not);
49+
50+
if (s.AllOf is not null)
51+
{
52+
foreach (var sub in s.AllOf)
53+
{
54+
Strip(sub);
55+
}
56+
}
57+
58+
if (s.OneOf is not null)
59+
{
60+
foreach (var sub in s.OneOf)
61+
{
62+
Strip(sub);
63+
}
64+
}
65+
66+
if (s.AnyOf is not null)
67+
{
68+
foreach (var sub in s.AnyOf)
69+
{
70+
Strip(sub);
71+
}
72+
}
73+
}
74+
}

src/SharedKernel/OpenApi/OpenApiExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ public static WebApplicationBuilder AddOpenApi(this WebApplicationBuilder builde
3030
builder.Services.AddOpenApi(document.GroupName,
3131
options =>
3232
{
33-
options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_0;
33+
options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_1;
3434
options.AddDocumentTransformer<RemoveServersTransformer>();
3535
options.AddDocument(document, openApiConfiguration);
3636
options.AddSchemaTransformer<EnumSchemaTransformer>();
37+
options.AddSchemaTransformer<NumericStringUnionTransformer>();
3738
options.UseApiSecuritySchemes(openApiConfiguration);
3839
options.AddDocumentTransformer<TagOrderingTransformer>();
3940
configureOptions?.Invoke(options);

src/SharedKernel/SharedKernel.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
<PackageIcon>pandatech.png</PackageIcon>
2222
<PackageReadmeFile>README.md</PackageReadmeFile>
2323

24-
<Version>2.2.7</Version>
25-
<PackageReleaseNotes>Downgrade OpenAPI 3.1 to 3.0</PackageReleaseNotes>
24+
<Version>2.2.8</Version>
25+
<PackageReleaseNotes>Restore OpenAPI 3.1 and fix numeric schemas rendered as string union (workaround for dotnet/aspnetcore#58882, #64145)</PackageReleaseNotes>
2626

2727
<GenerateDocumentationFile>true</GenerateDocumentationFile>
2828
<IncludeSymbols>true</IncludeSymbols>

0 commit comments

Comments
 (0)