Skip to content

Support discriminator for oneOf in OpenApiValidationPlugin - #2042

Open
waldekmastykarz wants to merge 13 commits into
dotnet:mainfrom
waldekmastykarz:oneof-discriminator
Open

waldekmastykarz wants to merge 13 commits into
dotnet:mainfrom
waldekmastykarz:oneof-discriminator

Conversation

@waldekmastykarz

Copy link
Copy Markdown
Collaborator

Closes #2040

Depends on #2037. This PR is based on #2037's branch, so its diff includes #2037's commits until #2037 merges.

Changes

When a schema with oneOf defines a discriminator and the value is an object, OpenApiValidationPlugin now selects the oneOf branch from the discriminator property's value and validates only that branch, instead of requiring that the value match exactly one branch.

  • Branch selection uses an explicit mapping entry first, then the implicit component schema name (for example Cat for #/components/schemas/Cat).
  • The plugin reports the selected branch's validation errors directly.
  • It reports a clear error when the discriminator property is missing, isn't a string, or has a value that doesn't map to a schema. The unknown-value error lists the allowed values.
  • If a discriminator defines defaultMapping (OAS 3.2), the plugin uses it when the discriminator property is missing or its value is unknown.
  • oneOf without a discriminator is still validated strictly.

waldekmastykarz and others added 8 commits October 31, 2026 11:00
…nAPI specs

Adds a reporting plugin that validates intercepted requests and responses
against local OpenAPI specs (specFiles and/or specsFolder) and reports
undocumented paths/methods/status codes/content types, parameter issues
and request/response body schema violations. Closes dotnet#779

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Report schemas nested deeper than the supported maximum instead of treating them as valid
- Search all specs and matching paths for the requested method before reporting it as undocumented
- Recognize required deepObject query parameters
- Match operations against their effective (document-, path- or operation-level) servers
- Match server base paths and request paths case-sensitively and strictly on trailing slashes
- Decode array parameters according to their style and explode settings
- Reject non-finite numbers when coercing parameter values

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Memoize composed (allOf/anyOf/oneOf) subschema results per schema and
value, dedupe repeated allOf errors, and cap total evaluations as a
backstop so repeated references can't cause exponential validation work.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Use unambiguous property paths so memoized results don't collide
- Recognize exploded form-object query parameters
- Exempt bracketed query keys only for deepObject parameters
- Report malformed JSON even when the media type has no schema
- Match server URLs with explicit default ports
- Coerce parameter values using types declared via composition

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Type inference, item lookup and property discovery now traverse
allOf/anyOf/oneOf with a visited set, so repeated references and cycles
can't cause exponential work.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- When an allOf subschema with additionalProperties: false rejects a
  property declared in a sibling subschema, explain why in the message
- Skip validating JSON bodies larger than 5 MB to avoid stalling the
  proxy, and log that validation was skipped

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Dedupe allOf errors with a hash set instead of a linear scan
- Include depth in the composed-schema memo key so depth-limited results
  aren't reused at shallower depths
- Accept parameter values that are valid as strings when the coerced
  value isn't, e.g. for schemas allowing both integers and strings

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 31, 2026 15:27
@waldekmastykarz waldekmastykarz self-assigned this Oct 31, 2026
@waldekmastykarz
waldekmastykarz requested a review from a team as a code owner October 31, 2026 15:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved schema-validation and path-matching defects can reject valid requests or responses, accept enum-disallowed nulls, and treat undocumented methods as documented operations.

5 open issues
What changed in this PR

Adds discriminator-based oneOf selection to OpenApiValidationPlugin, building on the traffic-validation functionality included from #2037.

Changes:

  • Selects branches using explicit mappings, implicit schema names, or OAS 3.2 defaultMapping.
  • Reports selected-branch errors and invalid discriminator values while preserving strict oneOf validation without a discriminator.
  • Includes plugin configuration, reporting, and integration tests for traffic validation and discriminator behavior.
File Description
schemas/​v4.1.0/​openapivalidationplugin.schema.json Defines spec sources and unmatched-request reporting options.
DevProxy.Plugins/​Utils/​OpenApiSchemaValidator.cs Implements schema validation and discriminator-based branch selection.
DevProxy.Plugins/​Reporting/​OpenApiValidationPluginReport.cs Formats validation results as Markdown and plain text.
DevProxy.Plugins/​Reporting/​OpenApiValidationPlugin.cs Loads specs, validates traffic, and records reports.
DevProxy.Integration.Tests/​OpenApiValidationPluginTests.cs Covers traffic validation, discriminator selection, errors, and fallback behavior.

Review effort: Balanced

- Most specific matching path takes precedence; a missing method is reported as undocumented
- OpenAPI 3.1+ specs require null to be listed in enums
- Honor readOnly/writeOnly declared in allOf subschemas and references

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
waldekmastykarz and others added 3 commits October 31, 2026 16:50
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes dotnet#2040

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The discriminator mapping can resolve to a schema outside the declared oneOf alternatives, allowing unrelated payloads to bypass validation.

1 open issue
5 resolved since last review

Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Human review is needed to assess a discriminator-mapping edge case where the allowed-values hint can recommend a selection that validation rejects.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support discriminator for oneOf in OpenApiValidationPlugin

2 participants