Repository navigation
Do not ignore multiple types when serializing to 3.0 - #2960
Gavin Barron (gavinbarron) merged 8 commits into
Conversation
165e0eb to
a663f6f
Compare
There was a problem hiding this comment.
Pull request overview
This pull request updates OpenApiSchema JSON serialization to properly represent schemas with multiple JsonSchemaType flags when targeting OpenAPI 3.0, emitting anyOf/oneOf (when possible) instead of silently ignoring additional types, and adds coverage to validate the new behavior.
Changes:
- Split type serialization logic between OpenAPI 2.0 and OpenAPI 3.0+ paths, adding 3.0-specific handling for multi-type schemas via
anyOf/oneOf. - Add comprehensive unit tests covering multi-type combinations (with/without
null, and with existingoneOf/anyOfpresent). - Simplify
ToSingleIdentifierby using a lookup and providing a clearer exception for unexpected values.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs | Adds tests validating multi-type serialization behavior for OpenAPI 3.0 across multiple composition scenarios. |
| src/Microsoft.OpenApi/Models/OpenApiSchema.cs | Refactors and extends type serialization to support multi-type handling in 3.0 using anyOf/oneOf, keeping 2.0 behavior unchanged. |
| src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs | Updates ToSingleIdentifier to use a lookup and throw a clearer exception for unexpected inputs. |
Comments suppressed due to low confidence (1)
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1091
- In the v3.1+ path, TrySerializeTypePropertyForVersion3AndLater also assumes Enum.GetValues() will match at least one flag in the provided Type. If Type is 0 or contains only unknown bits, array will be empty and array[0] will throw IndexOutOfRangeException. Add an empty-array guard and return false when no valid flags are present.
var array = (from JsonSchemaType flag in jsonSchemaTypeValues
where type.HasFlag(flag)
select flag).ToArray();
if (array.Length > 1)
{
writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => w.WriteValue(s.ToSingleIdentifier()));
}
else
{
writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier());
}
Given the investigations I did for #2967, I think it's fine for us to continue ensuring, as much as possible, that we produce semantically equivalent document for all versions. The cases presented in #2967 fall into two groups:
I don't believe there is a need for a new public API to do the semantic transformations, and I don't think all transformations we might want to do in future will be representable in the object model. So we will end up with logic scattered between dedicated walkers and in the serialization itself. We shouldn't need to pay additional performance cost for deep cloning the whole document as well. In all cases, we can always decide to move the logic to a walker in the future, if really necessary. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (4)
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1088
- In the OpenAPI 3.1+ branch,
array[0]is used whenarray.Length <= 1. IfTypeis 0 or contains no known flags,arraywill be empty and this will throwIndexOutOfRangeException.
}
else
{
writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier());
}
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1073
arrayWithoutNull[0]is accessed without guarding forarrayWithoutNull.Length == 0. IfTypeis set to an unexpected value (e.g., 0 / no flags, or only unknown bits), this will throwIndexOutOfRangeExceptionduring OpenAPI 3.0 serialization.
else
{
writer.WriteProperty(OpenApiConstants.Type, arrayWithoutNull[0].ToSingleIdentifier());
return;
}
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1053
- For OpenAPI 3.0, when Type includes
nulland multiple non-null types, this path represents null by adding a child schema withType = Nullinto anyOf/oneOf. HoweverSerializeNullablewill still emit top-levelnullable: truewheneverHasNullTypeis true, even though there is no top-leveltypein that case. This produces redundant/ineffective output and contradicts the new tests that expect nonullablewhen null is represented via anyOf/oneOf.
This issue also appears in the following locations of the same file:
- line 1069
- line 1084
// - If we have more than one type (excluding null), we have to use anyOf/oneOf.
// - If we have exactly one type alone (without null), we emit the type property.
// - If we have exactly one non-null type and also we have the null type, we emit the type property and nullable: true (handled in SerializeNullable)
if (arrayWithoutNull.Length > 1)
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1029
- This XML doc uses a
<returns>block, but the method returnsvoid. Either remove the<returns>documentation or change the method signature to return a value (and use it at the call site).
/// <returns>
/// true if the Type was serializable using "type" property, and false if
/// it serialized using anyOf/oneOf or if it couldn't be serialized at all.
/// </returns>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (5)
test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs:147
- The test name says it "OmitsType", but the updated expected JSON now writes multiple types via anyOf (and also keeps nullable). Renaming the test would better match the behavior being asserted.
public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNullable()
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1029
- XML documentation has a section describing a boolean return value, but SerializeTypePropertyForVersion3AndLater returns void. This makes the docs misleading for future maintainers.
/// <summary>
/// Tries to serialize the "type" property for OpenAPI v3 and later versions.
/// </summary>
/// <returns>
/// true if the Type was serializable using "type" property, and false if
/// it serialized using anyOf/oneOf or if it couldn't be serialized at all.
/// </returns>
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1048
- For OpenAPI 3.0, if Type is set to an empty flags value (e.g., (JsonSchemaType)0), typeWithoutNull will produce no flags and arrayWithoutNull will be empty. The current code then falls into the single-type branch and indexes arrayWithoutNull[0], which will throw IndexOutOfRangeException.
var typeWithoutNull = type & ~JsonSchemaType.Null;
var hasNull = typeWithoutNull != type;
var arrayWithoutNull = (from JsonSchemaType flag in jsonSchemaTypeValues
where typeWithoutNull.HasFlag(flag)
select flag).ToArray();
src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1079
- For OpenAPI versions other than 3.0, if Type is an empty flags value ((JsonSchemaType)0), the computed array will be empty and the code will index array[0], throwing IndexOutOfRangeException.
var array = (from JsonSchemaType flag in jsonSchemaTypeValues
where type.HasFlag(flag)
select flag).ToArray();
test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs:121
- The test name says it "OmitsType", but the updated expected JSON now writes multiple types via anyOf. Renaming the test would keep intent clear and avoid future confusion.
This issue also appears on line 147 of the same file.
public async Task SerializeMultipleNonNullTypesAsV3OmitsType()
Updated [Microsoft.AspNetCore.OpenApi](https://github.com/dotnet/dotnet) from 10.0.12 to 10.0.14. <details> <summary>Release notes</summary> _Sourced from [Microsoft.AspNetCore.OpenApi's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Updated [Microsoft.CodeAnalysis.CSharp](https://github.com/dotnet/roslyn) from 4.14.0 to 5.9.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.CodeAnalysis.CSharp's releases](https://github.com/dotnet/roslyn/releases)._ ## 5.0.4 [Release](https://github.com/dotnet/core/releases/tag/v5.0.4) ## 5.0.2 [Release Notes](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.2/5.0.2.md) [Install Instructions](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.2/5.0.2-install-instructions.md) # Repos * [Core](https://github.com/dotnet/core/releases/tag/v5.0.2) ## 5.0.1 [Release Notes](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.1/5.0.1.md) [Install Instructions](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.1/5.0.1-install-instructions.md) # Repo * [Core](https://github.com/dotnet/core/releases/tag/v5.0.1) Commits viewable in [compare view](https://github.com/dotnet/roslyn/commits). </details> Updated [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 18.10.1 to 18.11.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.NET.Test.Sdk's releases](https://github.com/microsoft/vstest/releases)._ ## 18.11.0 <!-- Release notes generated using configuration in .github/release.yml at rel/18.11 --> ## What's Changed * Fix TRX logger mangling astral-plane (non-BMP) characters by @azat-msft in microsoft/vstest#16318 * Disable the MTP testhost by default by @nohwnd in microsoft/vstest#16337 * Fix OS-blind apphost probe in MTP bridge on Unix (regression from #16201) by @azat-msft in microsoft/vstest#16336 * Retarget the MTP client onto Microsoft.Testing.Platform.ServerMode.Client.Sources by @nohwnd in microsoft/vstest#16300 * Pass arguments to PowerShell with -File instead of -command by @nohwnd in microsoft/vstest#16363 * Respect console logger verbosity from a settings file by @nohwnd in microsoft/vstest#16044 * Fix backslash normalization in VSTestCLIRunSettings on Unix by @nohwnd in microsoft/vstest#15795 * Docs: fix typo explicitely -> explicitly by @vaibhav8a in microsoft/vstest#16397 * Copy acceptance test diagnostic logs into the test results directory by @nohwnd in microsoft/vstest#16403 ## New Contributors * @vaibhav8a made their first contribution in microsoft/vstest#16397 **Full Changelog**: microsoft/vstest@v18.10.1...v18.11.0 Commits viewable in [compare view](microsoft/vstest@v18.10.1...v18.11.0). </details> Updated [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) from 2.12.0 to 3.11.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.OpenApi's releases](https://github.com/Microsoft/OpenAPI.NET/releases)._ ## 3.11.0 ## [3.11.0](microsoft/OpenAPI.NET@v3.10.2...v3.11.0) (2026-10-19) ### Features * **document:** add GetOperationById to search operations across path… ([#3025](microsoft/OpenAPI.NET#3025)) ([1dae1ff](microsoft/OpenAPI.NET@1dae1ff)) ### Bug Fixes * components-key validation timeouts under load ([#3108](microsoft/OpenAPI.NET#3108)) ([01d4729](microsoft/OpenAPI.NET@01d4729)) * **openapi:** omit null response descriptions ([afd4967](microsoft/OpenAPI.NET@afd4967)) * **serialization:** potential infinite loop when inlining references ([c6ef130](microsoft/OpenAPI.NET@c6ef130)) * **serialization:** references inlining ([#3124](microsoft/OpenAPI.NET#3124)) ([c6ef130](microsoft/OpenAPI.NET@c6ef130)) ## 3.10.2 ## [3.10.2](microsoft/OpenAPI.NET@v3.10.1...v3.10.2) (2026-08-20) ### Bug Fixes * duplicate schema example when serializing to v2 ([#3045](microsoft/OpenAPI.NET#3045)) ([50f5a2b](microsoft/OpenAPI.NET@50f5a2b)) ## 3.10.1 ## [3.10.1](microsoft/OpenAPI.NET@v3.10.0...v3.10.1) (2026-08-19) ### Bug Fixes * circular ref guard ([#3033](microsoft/OpenAPI.NET#3033)) ([8018d40](microsoft/OpenAPI.NET@8018d40)) * harden yaml parsing ([#3027](microsoft/OpenAPI.NET#3027)) ([e0d5e9d](microsoft/OpenAPI.NET@e0d5e9d)) ## 3.10.0 ## [3.10.0](microsoft/OpenAPI.NET@v3.9.0...v3.10.0) (2026-08-11) ### Features * adds deserialization of the example extension ([e5a1080](microsoft/OpenAPI.NET@e5a1080)) * do not ignore multiple types when serializing to 3.0 ([#2960](microsoft/OpenAPI.NET#2960)) ([ebaf27a](microsoft/OpenAPI.NET@ebaf27a)) * serialize license identifier as extension for earlier versions ([d090989](microsoft/OpenAPI.NET@d090989)) * serialize license identifier as extension for earlier versions ([60971ba](microsoft/OpenAPI.NET@60971ba)) ### Bug Fixes * better nullability round-tripping ([655c2c8](microsoft/OpenAPI.NET@655c2c8)) * bound YAML anchor/alias expansion to prevent OOM (billion laughs) ([#3000](microsoft/OpenAPI.NET#3000)) ([2179326](microsoft/OpenAPI.NET@2179326)) * deserialize metadata url from extension in earlier version ([9387b01](microsoft/OpenAPI.NET@9387b01)) * marks deprecated properties from the specification as obsolete ([787b045](microsoft/OpenAPI.NET@787b045)) * marks deprecated properties from the specification as obsolete ([953c22a](microsoft/OpenAPI.NET@953c22a)) * **schema:** serialize compatibility examples from examples list ([5d8ec3a](microsoft/OpenAPI.NET@5d8ec3a)) * serialize examples as extension in v2/v3 ([ff1dbc9](microsoft/OpenAPI.NET@ff1dbc9)) * serialize examples as extension in v2/v3 ([edf3c67](microsoft/OpenAPI.NET@edf3c67)) ## 3.9.0 ## [3.9.0](microsoft/OpenAPI.NET@v3.8.0...v3.9.0) (2026-07-15) ### Features * adds support for anchor and id external resolution ([1591007](microsoft/OpenAPI.NET@1591007)) * **schema:** resolve bare $dynamicRef via $dynamicAnchor index ([#2913](microsoft/OpenAPI.NET#2913)) ([eacc2fc](microsoft/OpenAPI.NET@eacc2fc)) * support relative URI resolution in $dynamicRef ([#2928](microsoft/OpenAPI.NET#2928)) ([#2945](microsoft/OpenAPI.NET#2945)) ([821053b](microsoft/OpenAPI.NET@821053b)) ### Bug Fixes * adds explicit error message for invalid json pointers ([63fc55d](microsoft/OpenAPI.NET@63fc55d)) * adds explicit error message for invalid json pointers ([bc93efe](microsoft/OpenAPI.NET@bc93efe)) * default mapping is not being serialized with the correct shape ([fe4a25f](microsoft/OpenAPI.NET@fe4a25f)) * differentiate unset value from null value in OpenApiSchema.Const ([#2936](microsoft/OpenAPI.NET#2936)) ([07b525f](microsoft/OpenAPI.NET@07b525f)) * handle nullability more accurately during serialization for 3.0/2.0 ([#2933](microsoft/OpenAPI.NET#2933)) ([0ace243](microsoft/OpenAPI.NET@0ace243)) * validate required properties of security scheme before serialization ([#2952](microsoft/OpenAPI.NET#2952)) ([f31b192](microsoft/OpenAPI.NET@f31b192)) ## 3.8.0 ## [3.8.0](microsoft/OpenAPI.NET@v3.7.0...v3.8.0) (2026-07-03) ### Features * add JsonConverter for OpenApiSchema System.Text.Json serialization ([#2915](microsoft/OpenAPI.NET#2915)) ([2f8b3d2](microsoft/OpenAPI.NET@2f8b3d2)) * **library:** support schema keywords on references ([434b2f8](microsoft/OpenAPI.NET@434b2f8)) * **library:** support schema keywords on references ([66a9d04](microsoft/OpenAPI.NET@66a9d04)), closes [#2903](microsoft/OpenAPI.NET#2903) ### Bug Fixes * Don't silently skip null assignment to OpenApiDocument.Tags ([3764142](microsoft/OpenAPI.NET@3764142)) * handling of nullable enums for 3.0 ([#2920](microsoft/OpenAPI.NET#2920)) ([beb68f5](microsoft/OpenAPI.NET@beb68f5)) * **library:** keep v3 schema references ref-only ([c938727](microsoft/OpenAPI.NET@c938727)) * preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+ ([#2896](microsoft/OpenAPI.NET#2896)) ([08160c8](microsoft/OpenAPI.NET@08160c8)) * use async method for crypto flush ([6e675d9](microsoft/OpenAPI.NET@6e675d9)) ## 3.7.0 ## [3.7.0](microsoft/OpenAPI.NET@v3.6.0...v3.7.0) (2026-06-10) ### Features * add contains/minContains/maxContains members ([78475e3](microsoft/OpenAPI.NET@78475e3)) * add contains/minContains/maxContains members ([1a974f8](microsoft/OpenAPI.NET@1a974f8)) * **library:** add missing json schema properties ([9b1aed6](microsoft/OpenAPI.NET@9b1aed6)) * **library:** add missing json schema properties ([82f84e0](microsoft/OpenAPI.NET@82f84e0)) ### Bug Fixes * **library:** always copy unevaluated properties ([4907d1c](microsoft/OpenAPI.NET@4907d1c)) * **library:** avoid false circular refs for external schema re-exports ([b635242](microsoft/OpenAPI.NET@b635242)) * **library:** avoid false circular refs for external schema re-exports ([7a443c2](microsoft/OpenAPI.NET@7a443c2)) * **library:** remove unshipped schema extension fallback ([cf54bb3](microsoft/OpenAPI.NET@cf54bb3)) * **library:** use version-specific schema keyword callbacks ([6e22ec6](microsoft/OpenAPI.NET@6e22ec6)) * **library:** use x-jsonschema schema extensions ([eb1891a](microsoft/OpenAPI.NET@eb1891a)) ## 3.6.0 ## [3.6.0](microsoft/OpenAPI.NET@v3.5.5...v3.6.0) (2026-06-01) ### Features * **reader:** remove ParseNode infrastructure ([9b4f45b](microsoft/OpenAPI.NET@9b4f45b)) * Significant performance improvements resulting ~40% reduced allocations when parsing JSON descriptions, ~25% for YAML. ## 3.5.5 ## [3.5.5](microsoft/OpenAPI.NET@v3.5.4...v3.5.5) (2026-05-28) ### Bug Fixes * **reader:** preserve Null flag when nullable appears before type in V3.0/V3.1/V3.2 deserializers ([2b9d7f4](microsoft/OpenAPI.NET@2b9d7f4)) ## 3.5.4 ## [3.5.4](microsoft/OpenAPI.NET@v3.5.3...v3.5.4) (2026-05-26) ### Bug Fixes * **library:** handle circular schema references ([b3cd42b](microsoft/OpenAPI.NET@b3cd42b)) * **library:** handle circular schema references ([91a989f](microsoft/OpenAPI.NET@91a989f)) ## 3.5.3 ## [3.5.3](microsoft/OpenAPI.NET@v3.5.2...v3.5.3) (2026-04-27) ### Bug Fixes * null reference exception for boolean component schemas ([f97f91a](microsoft/OpenAPI.NET@f97f91a)) * null reference exception for boolean component schemas ([fe0b50a](microsoft/OpenAPI.NET@fe0b50a)) * **schema:** support boolean schemas in deserializer for OpenAPI 3.1/3.2 ([05b44be](microsoft/OpenAPI.NET@05b44be)) ### Performance Improvements * **schema:** optimize boolean schema deserialization ([7316e3f](microsoft/OpenAPI.NET@7316e3f)) ## 3.5.2 ## [3.5.2](microsoft/OpenAPI.NET@v3.5.1...v3.5.2) (2026-04-14) ### Bug Fixes * **hidi:** update Microsoft.OpenApi.OData to 3.2.1 ([b0a68fb](microsoft/OpenAPI.NET@b0a68fb)) * **hidi:** update Microsoft.OpenApi.OData to 3.2.1 ([8c22ab2](microsoft/OpenAPI.NET@8c22ab2)), closes [#2811](microsoft/OpenAPI.NET#2811) ## 3.5.1 ## [3.5.1](microsoft/OpenAPI.NET@v3.5.0...v3.5.1) (2026-03-31) ### Bug Fixes * security scheme references serialization ([a5acb89](microsoft/OpenAPI.NET@a5acb89)) ## 3.5.0 ## [3.5.0](microsoft/OpenAPI.NET@v3.4.0...v3.5.0) (2026-03-20) ### Features * **library:** add Extensions support for schema references in v3.1/v3.2; add SerializeAsV32 with loop detection ([9b422bf](microsoft/OpenAPI.NET@9b422bf)) ### Bug Fixes * a bug where path parameter validation would fail if they contained forbidden JSON pointer characters ([ef55b2c](microsoft/OpenAPI.NET@ef55b2c)) * a bug where path parameter validation would fail if they contained forbidden JSON pointer characters ([4b3164a](microsoft/OpenAPI.NET@4b3164a)) * double encoding of json pointer for invalid reference rule ([b246cd0](microsoft/OpenAPI.NET@b246cd0)) * encoding of special characters for JSON paths ([4c757e1](microsoft/OpenAPI.NET@4c757e1)) * **library:** do not emit unevaluatedProperties for non-object schemas ([852fb4c](microsoft/OpenAPI.NET@852fb4c)) * **library:** do not emit unevaluatedProperties for non-object schemas ([19538aa](microsoft/OpenAPI.NET@19538aa)) * **library:** enforce spec-compliant $ref serialization; add Extensions support for schema references in v3.1/v3.2 ([9bf61de](microsoft/OpenAPI.NET@9bf61de)) * potential double encoding of paths ([471a61a](microsoft/OpenAPI.NET@471a61a)) ## 3.4.0 ## [3.4.0](microsoft/OpenAPI.NET@v3.3.1...v3.4.0) (2026-03-04) ### Features * **library:** preserve PatternProperties as x-jsonschema-patternProperties extension for OpenAPI v2/v3.0 serialization ([d969fdc](microsoft/OpenAPI.NET@d969fdc)) * **library:** Preserve PatternProperties via x-jsonschema-patternProperties extension for OpenAPI v2/v3.0 ([16ab5e4](microsoft/OpenAPI.NET@16ab5e4)) * **securityscheme:** add oauth2MetadataUrl support (OpenAPI 3.2) ([4509488](microsoft/OpenAPI.NET@4509488)) ### Bug Fixes * implement unevaluatedProperties as schema per JSON Schema 2020-12 ([#2728](microsoft/OpenAPI.NET#2728)) ([7c13fb3](microsoft/OpenAPI.NET@7c13fb3)) * **library:** serialize additionalProperties schema in OpenAPI V2 ([f3165fa](microsoft/OpenAPI.NET@f3165fa)) * **library:** serialize additionalProperties schema in OpenAPI V2 documents ([3d07756](microsoft/OpenAPI.NET@3d07756)) * optimize parsing V3.1 documents by reducing GetLocation method allocation on hot path([#2748](microsoft/OpenAPI.NET#2748)) ([f690681](microsoft/OpenAPI.NET@f690681)) ## 3.3.1 ## [3.3.1](microsoft/OpenAPI.NET@v3.3.0...v3.3.1) (2026-01-22) ### Features * **models:** add shared Content interface ([#2695](microsoft/OpenAPI.NET#2695)) ([338566f](microsoft/OpenAPI.NET@338566f)) ### Bug Fixes * broken binary compatibility due to interface changes in previous version ([d96bba7](microsoft/OpenAPI.NET@d96bba7)) ## 3.3.0 ## [3.3.0](microsoft/OpenAPI.NET@v3.2.0...v3.3.0) (2026-01-21) ### Features * **models:** add shared Content interface ([9e13b25](microsoft/OpenAPI.NET@9e13b25)) * **models:** add shared Content interface ([#2695](microsoft/OpenAPI.NET#2695)) ([9e13b25](microsoft/OpenAPI.NET@9e13b25)) * **models:** support mutualTLS security scheme ([a4efdfe](microsoft/OpenAPI.NET@a4efdfe)) ## 3.2.0 ## [3.2.0](microsoft/OpenAPI.NET@v3.1.3...v3.2.0) (2026-01-19) ### Features * hidi validate command now logs warnings ([76a3c0f](microsoft/OpenAPI.NET@76a3c0f)) * hidi validate command now logs warnings ([62e7d56](microsoft/OpenAPI.NET@62e7d56)) ### Bug Fixes * discriminator property validation fails any/allOf cases when it shouldn't ([fb6cecc](microsoft/OpenAPI.NET@fb6cecc)) * discriminator property validation fails any/allOf cases when it shouldn't ([a8fb81c](microsoft/OpenAPI.NET@a8fb81c)) ## 3.1.3 ## [3.1.3](microsoft/OpenAPI.NET@v3.1.2...v3.1.3) (2026-01-16) ### Bug Fixes * Support custom tag ordering ([008576c](microsoft/OpenAPI.NET@008576c)) * Support custom tag ordering ([7610d07](microsoft/OpenAPI.NET@7610d07)) ## 3.1.2 ## [3.1.2](microsoft/OpenAPI.NET@v3.1.1...v3.1.2) (2026-01-06) ### Bug Fixes * correct error pointer when extension parser throws OpenApiException ([43c75a9](microsoft/OpenAPI.NET@43c75a9)) * wrap extension parser calls in try-catch to ensure correct error pointers ([50b44aa](microsoft/OpenAPI.NET@50b44aa)) ## 3.1.1 ## [3.1.1](microsoft/OpenAPI.NET@v3.1.0...v3.1.1) (2025-12-18) ### Bug Fixes * **schema:** always serialize `additionalProperties: false` ([6651c36](microsoft/OpenAPI.NET@6651c36)) * **schema:** always serialize `additionalProperties: false` ([e36fc95](microsoft/OpenAPI.NET@e36fc95)) ## 3.1.0 ## [3.1.0](microsoft/OpenAPI.NET@v3.0.3...v3.1.0) (2025-12-17) ### Features * Add `type: "null"` downcasting when in oneOf and anyOf for OpenAPI v3 ([782cf8d](microsoft/OpenAPI.NET@782cf8d)) ## 3.0.3 ## [3.0.3](microsoft/OpenAPI.NET@v3.0.2...v3.0.3) (2025-12-16) ### Bug Fixes * load JSON documents that are preceded by multiple whitespace ([6461bac](microsoft/OpenAPI.NET@6461bac)) * non-seekable json streams would fail to load as a document ([2436d73](microsoft/OpenAPI.NET@2436d73)) * reading streams in an asp.net context would cause async exceptions ([f9e5248](microsoft/OpenAPI.NET@f9e5248)) ## 3.0.2 ## [3.0.2](microsoft/OpenAPI.NET@v3.0.1...v3.0.2) (2025-12-08) ### Bug Fixes * additional properties serialization should not emit a schema in v2 ([946cba9](microsoft/OpenAPI.NET@946cba9)) * additional properties serialization should not emit booleans in v3.1+ ([946cba9](microsoft/OpenAPI.NET@946cba9)) ## 3.0.1 ## [3.0.1](microsoft/OpenAPI.NET@v3.0.0...v3.0.1) (2025-11-17) ### Bug Fixes * empty strings should be quoted in yaml ([8d215f9](microsoft/OpenAPI.NET@8d215f9)) * empty strings should be quoted in yaml ([0ca10db](microsoft/OpenAPI.NET@0ca10db)) ## 3.0.0 ## [3.0.0](microsoft/OpenAPI.NET@v2.3.9...v3.0.0) (2025-11-11) ### ⚠ BREAKING CHANGES * adds support for OpenAPI 3.2.0 > Note: Please refer to the [upgrade guide](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-3.md) for a detailed description of the breaking changes. > Note: ASP.net users should remain on version 1.X for ASP.net < 10, and version 2.X for ASP.net 10, this new major version will be implemented in a future version of ASP.net, [more information](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md#branches-and-support-policy) ### Features * adds support for OpenAPI 3.2.0 ([765a8dd](microsoft/OpenAPI.NET@765a8dd)) ### Special thanks - [Matthieu Costabello](https://github.com/kilifu) ## 2.13.0 ## [2.13.0](microsoft/OpenAPI.NET@v2.12.2...v2.13.0) (2026-10-19) ### Features * **document:** add GetOperationById to search operations across path… ([#3025](microsoft/OpenAPI.NET#3025)) ([#3074](microsoft/OpenAPI.NET#3074)) ([75d6cea](microsoft/OpenAPI.NET@75d6cea)) ### Bug Fixes * components-key validation timeouts under load ([#3108](microsoft/OpenAPI.NET#3108)) ([#3112](microsoft/OpenAPI.NET#3112)) ([5369417](microsoft/OpenAPI.NET@5369417)) * **openapi:** omit null response descriptions ([1344a43](microsoft/OpenAPI.NET@1344a43)) ## 2.12.2 ## [2.12.2](microsoft/OpenAPI.NET@v2.12.1...v2.12.2) (2026-08-20) ### Bug Fixes * duplicate schema example when serializing to v2 ([#3046](microsoft/OpenAPI.NET#3046)) ([a6366be](microsoft/OpenAPI.NET@a6366be)) ## 2.12.1 ## [2.12.1](microsoft/OpenAPI.NET@v2.12.0...v2.12.1) (2026-08-19) ### Bug Fixes * circular ref guard ([#3033](microsoft/OpenAPI.NET#3033)) ([#3039](microsoft/OpenAPI.NET#3039)) ([406e6fd](microsoft/OpenAPI.NET@406e6fd)) * harden yaml parsing ([#3034](microsoft/OpenAPI.NET#3034)) ([fdc5718](microsoft/OpenAPI.NET@fdc5718)) Commits viewable in [compare view](microsoft/OpenAPI.NET@v2.12.0...v3.11.0). </details> Updated [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 6.3.0 to 6.3.1. <details> <summary>Release notes</summary> _Sourced from [NUnit3TestAdapter's releases](https://github.com/nunit/nunit3-vs-adapter/releases)._ ## 6.3.1 This is a hotfix release for issue [1504](nunit/nunit3-vs-adapter#1504) Commits viewable in [compare view](nunit/nunit3-vs-adapter@V6.3.0...V6.3.1). </details> Updated [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) from 10.2.3 to 10.3.1. <details> <summary>Release notes</summary> _Sourced from [Swashbuckle.AspNetCore's releases](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases)._ ## 10.3.1 ## What's Changed * Remove Swashbuckle.AspNetCore.ApiTesting.Xunit by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4188 * Migrate to xunit v3 by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4189 * Normalize line endings by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4190 * Update .git-blame-ignore-revs by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4191 * Fix `AmbiguousMatchException` for `[FromQuery]` by @SENESO in domaindrivendev/Swashbuckle.AspNetCore#4209 * Avoid deadlock when a schema filter depends on `ISerializerDataContractResolver` by @DevKaurav-14 in domaindrivendev/Swashbuckle.AspNetCore#4210 * Fix tests by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4214 ## Deprecations > [!IMPORTANT] > Swashbuckle.AspNetCore.ApiTesting.Xunit depended on Xunit v2, which is no longer supported. > > The package has been removed and no further versions will be released. ## New Contributors * @SENESO made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4209 * @DevKaurav-14 made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4210 **Full Changelog**: domaindrivendev/Swashbuckle.AspNetCore@v10.3.0...v10.3.1 ## 10.3.0 ## What's Changed * Change nullability handling for schemas with `anyOf`, `allOf`, `oneOf` or `type = null` by @ldeluigi in domaindrivendev/Swashbuckle.AspNetCore#3976 * Handle leading slash on route prefix during index.html GET by @superstator in domaindrivendev/Swashbuckle.AspNetCore#4084 * Move NRT handling to DataContractResolver by @desjoerd in domaindrivendev/Swashbuckle.AspNetCore#3998 * Clarify nullable behaviour by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4094 * Fix review issues for caching and encoding by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4093 * Support multiple response types per status code by @DeagleGross in domaindrivendev/Swashbuckle.AspNetCore#4100 * Add coverage for `AddServer` across multiple documents by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4115 * Fix Swagger sort key fallback for empty endpoint tags metadata by @AleksaMCode in domaindrivendev/Swashbuckle.AspNetCore#4125 * Fix parameter matching to consider location when names collide by @nonsoikem in domaindrivendev/Swashbuckle.AspNetCore#4126 * Emit form encoding for properties of a complex form parameter by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4128 * Keep a property's own summary when comments come from several XML files by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4129 * Strip query string from relative document URLs in Swagger UI by @GabeSilvaDev in domaindrivendev/Swashbuckle.AspNetCore#4152 * Document that System.Text.Json ignores `[EnumMember]` by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4127 * Drop the regex route constraint from the default Swagger route by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4130 * Serialize custom values in the UI `ConfigObject.AdditionalItems` by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4132 * Use Minimal APIs JSON options when MVC is not registered by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4116 * Resolve enum contracts against the underlying type under source generation by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4131 ## New Contributors * @ldeluigi made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#3976 * @superstator made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4084 * @desjoerd made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#3998 * @RaphaelFakhri made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4115 * @AleksaMCode made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4125 * @nonsoikem made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4126 * @GabeSilvaDev made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4152 * @JulianThoms made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4182 **Full Changelog**: domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.0 Commits viewable in [compare view](domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.1). </details> Updated [Swashbuckle.AspNetCore.SwaggerGen](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) from 10.2.3 to 10.3.1. <details> <summary>Release notes</summary> _Sourced from [Swashbuckle.AspNetCore.SwaggerGen's releases](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases)._ ## 10.3.1 ## What's Changed * Remove Swashbuckle.AspNetCore.ApiTesting.Xunit by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4188 * Migrate to xunit v3 by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4189 * Normalize line endings by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4190 * Update .git-blame-ignore-revs by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4191 * Fix `AmbiguousMatchException` for `[FromQuery]` by @SENESO in domaindrivendev/Swashbuckle.AspNetCore#4209 * Avoid deadlock when a schema filter depends on `ISerializerDataContractResolver` by @DevKaurav-14 in domaindrivendev/Swashbuckle.AspNetCore#4210 * Fix tests by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4214 ## Deprecations > [!IMPORTANT] > Swashbuckle.AspNetCore.ApiTesting.Xunit depended on Xunit v2, which is no longer supported. > > The package has been removed and no further versions will be released. ## New Contributors * @SENESO made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4209 * @DevKaurav-14 made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4210 **Full Changelog**: domaindrivendev/Swashbuckle.AspNetCore@v10.3.0...v10.3.1 ## 10.3.0 ## What's Changed * Change nullability handling for schemas with `anyOf`, `allOf`, `oneOf` or `type = null` by @ldeluigi in domaindrivendev/Swashbuckle.AspNetCore#3976 * Handle leading slash on route prefix during index.html GET by @superstator in domaindrivendev/Swashbuckle.AspNetCore#4084 * Move NRT handling to DataContractResolver by @desjoerd in domaindrivendev/Swashbuckle.AspNetCore#3998 * Clarify nullable behaviour by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4094 * Fix review issues for caching and encoding by @martincostello in domaindrivendev/Swashbuckle.AspNetCore#4093 * Support multiple response types per status code by @DeagleGross in domaindrivendev/Swashbuckle.AspNetCore#4100 * Add coverage for `AddServer` across multiple documents by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4115 * Fix Swagger sort key fallback for empty endpoint tags metadata by @AleksaMCode in domaindrivendev/Swashbuckle.AspNetCore#4125 * Fix parameter matching to consider location when names collide by @nonsoikem in domaindrivendev/Swashbuckle.AspNetCore#4126 * Emit form encoding for properties of a complex form parameter by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4128 * Keep a property's own summary when comments come from several XML files by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4129 * Strip query string from relative document URLs in Swagger UI by @GabeSilvaDev in domaindrivendev/Swashbuckle.AspNetCore#4152 * Document that System.Text.Json ignores `[EnumMember]` by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4127 * Drop the regex route constraint from the default Swagger route by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4130 * Serialize custom values in the UI `ConfigObject.AdditionalItems` by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4132 * Use Minimal APIs JSON options when MVC is not registered by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4116 * Resolve enum contracts against the underlying type under source generation by @RaphaelFakhri in domaindrivendev/Swashbuckle.AspNetCore#4131 ## New Contributors * @ldeluigi made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#3976 * @superstator made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4084 * @desjoerd made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#3998 * @RaphaelFakhri made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4115 * @AleksaMCode made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4125 * @nonsoikem made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4126 * @GabeSilvaDev made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4152 * @JulianThoms made their first contribution in domaindrivendev/Swashbuckle.AspNetCore#4182 **Full Changelog**: domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.0 Commits viewable in [compare view](domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.1). </details> Updated [System.CodeDom](https://github.com/dotnet/dotnet) from 10.0.12 to 10.0.14. <details> <summary>Release notes</summary> _Sourced from [System.CodeDom's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Paul Trampert <paul.trampert@ptrampert.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Paul Trampert <5550942+PaulTrampert@users.noreply.github.com>
Fixes #2939
ToSingleIdentifieris only a simplification to make it easier to read.Typehad multiple values (e.g, String and Integer). This is now handled usingoneOforanyOf(whichever isn't used by the current schema already). If both are used, we ignore as it we used to in the past.Type.Nullfrom it (if it exists).For context: https://spec.openapis.org/oas/v3.0.4.html#json-schema-keywords