fix: map numeric scalar unions with a format to the numeric type - #7994
fix: map numeric scalar unions with a format to the numeric type#7994FabienDehopre wants to merge 7 commits into
Conversation
ASP.NET Core's OpenAPI 3.1 generator emits numeric members as type ["integer"/"number", "string"] with a digit pattern under System.Text.Json's default JsonNumberHandling.AllowReadingFromString. GetPrimitiveType could not match the combined flags and returned null, so such properties degraded to UntypedNode. Prefer the numeric type by stripping the string flag when it is combined with integer or number. Scalar unions without a format keep being generated as composed type wrappers. Fixes microsoft#6541 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
This PR updates Kiota’s schema-to-primitive mapping so OpenAPI 3.1 numeric “scalar unions” emitted by ASP.NET Core (e.g. type: ["integer","string"] with format: int32) resolve to numeric primitives instead of degrading to UntypedNode, improving usability of generated SDK models.
Changes:
- Adjust
KiotaBuilder.GetPrimitiveTypeto prefer numeric types overstringwhen schema types combine numeric + string. - Add builder tests covering numeric/string unions with formats (and asserting existing no-format composed-type behavior for model properties).
- Document the behavior change in
CHANGELOG.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Kiota.Builder/KiotaBuilder.cs | Updates primitive type resolution logic for numeric+string scalar unions. |
| tests/Kiota.Builder.Tests/KiotaBuilderTests.cs | Adds regression tests for numeric/string scalar unions (format and no-format cases). |
| CHANGELOG.md | Notes the updated mapping behavior for numeric scalar unions with formats. |
|
@FabienDehopre can you also apply the copilot suggestions please? |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Both copilot suggestions have been applied. |
baywet
left a comment
There was a problem hiding this comment.
Thank you for making the changes!
…nion mapping The validator warned that the string type would be used for integer|string and number|string schemas with a numeric format, which is no longer true now that GetPrimitiveType maps those unions to the numeric type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The test project does not enable nullable reference types, so the string? parameter produced a CS8632 build warning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This reverts commit fbf5632.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/Kiota.Builder/Validation/InconsistentTypeFormatPair.cs:59
InconsistentTypeFormatPairwarning text still says “the string type will be used”, but after thesanitizedTypeadjustment (andKiotaBuilder.GetPrimitiveType’s default numeric fallbacks), numeric|string unions with an unsupported format will map to a numeric type (e.g.,Integer→integer) rather thanstring. This makes the warning misleading for the scenario this rule now targets.
context.CreateWarning(nameof(InconsistentTypeFormatPair), $"The format {schema.Format} is not supported by Kiota for the type {sanitizedType} and the string type will be used.");
Gate the numeric|string union special-case on Kiota's supported numeric formats so unions with a non-numeric format (uuid, date-time, ...) keep the previous untyped fallback instead of silently mapping to a numeric type. Also reword the InconsistentTypeFormatPair warning since the fallback is no longer necessarily string. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@baywet I did push some more commits to comply to all the remaining copilot suggestions. |
Fixes #6541
The problem
ASP.NET Core's OpenAPI 3.1 generator emits numeric members as a scalar union under System.Text.Json's default
JsonNumberHandling.AllowReadingFromString:KiotaBuilder.GetPrimitiveTypecomputes the combinedJsonSchemaTypeflags (Integer | String), which none of the switch arms match, so it returnsnulland the property degrades toUntypedNode— making these properties effectively unusable in the generated client. Since this is the out-of-the-box output of .NET 10's OpenAPI document generation, any ASP.NET Core API documented with the built-in generator hits this.The fix
In
GetPrimitiveType, when the schema type combinesStringwithIntegerorNumber, strip theStringflag before matching, so the numeric type (honoringformat) wins. This follows the direction suggested in #6541 (comment): emit numbers as numbers only.Scope is deliberately narrow:
formatare untouched: they never reach this code path for model properties (IsExclusiveUnion()routes them toCreateComposedModelDeclaration, which generates the composed type wrapper as before). A test asserts this behavior is preserved.["string", "boolean"], object unions, …) are untouched.Tests
["integer","string"]/["number","string"]withint32,int64,double,float, and the nullable variants (Nullflag), asserting the numeric type is generated.Kiota.Builder.Testssuite passes (2198 passed, 0 failed).public int? TemperatureC { get; set; }instead ofUntypedNode.🤖 Generated with Claude Code