Skip to content

Map [Obsolete] attribute to deprecated in OpenAPI documents - #66355

Merged
Youssef1313 merged 10 commits into
dotnet:mainfrom
fickleEfrit:obsolete-deprecated-openapi
Jul 22, 2026
Merged

Map [Obsolete] attribute to deprecated in OpenAPI documents#66355
Youssef1313 merged 10 commits into
dotnet:mainfrom
fickleEfrit:obsolete-deprecated-openapi

Conversation

@fickleEfrit

Copy link
Copy Markdown
Contributor

Map [Obsolete] attribute to deprecated in OpenAPI documents

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Map ObsoleteAttribute to deprecated: true on OpenAPI operations, schemas, and schema properties.

Description

Adds built-in support for mapping ObsoleteAttribute to the OpenAPI deprecated flag on operations, schemas, and schema properties. Previously, users had to write custom IOpenApiSchemaTransformer or IOpenApiOperationTransformer implementations to achieve this.

Operations

Endpoints with [Obsolete] on the handler method (minimal APIs) or action method (MVC controllers), or added via .WithMetadata(new ObsoleteAttribute()), now automatically emit deprecated: true on the OpenAPI operation.

Schemas (types)

Types decorated with [Obsolete] produce deprecated: true on the component schema.

Schema properties

  • Inline properties: [Obsolete] on a property sets deprecated: true directly on the property schema.
  • Referenced properties: [Obsolete] on a property whose type is componentized sets deprecated: true on the OpenApiSchemaReference, leaving the underlying component schema unchanged. This follows the same pattern used for [Description]x-ref-description.

Design notes

  • This follows the existing conventions for [Description]description and [Required]required, which are all automatic with no opt-out.
  • Uses inherit: false on GetCustomAttributes for type-level checks, so a derived type does not inherit deprecated from an obsolete base class.
  • The behavior is on by default. Users who need to suppress it for specific cases can use an IOpenApiSchemaTransformer or IOpenApiOperationTransformer to set Deprecated = false.

Breaking change consideration

This is a behavioral change. Existing users with [Obsolete] on types, properties, or endpoints will see deprecated: true appear in their generated OpenAPI documents after upgrading. This could affect downstream codegen tools. However, we believe this is the correct default — if something is marked obsolete in .NET, it should be reflected as deprecated in the API contract.

If the team prefers an opt-in/opt-out mechanism (e.g., a property on OpenApiOptions), that can be added.

Tests

  • 8 new tests covering all scenarios (type, inline property, referenced property, operations via attribute, metadata, and MVC actions)
  • Full existing test suite passes (837 passed, 0 failed)

Fixes #63494

Add built-in support for mapping ObsoleteAttribute to the OpenAPI
deprecated flag on operations, schemas, and schema properties.

- Operations: endpoints with [Obsolete] on the method or added via
  WithMetadata(new ObsoleteAttribute()) now emit deprecated: true
- Schemas: types decorated with [Obsolete] produce deprecated: true
  on the component schema
- Properties: [Obsolete] on properties sets deprecated: true on the
  property schema (inline) or on the schema reference (componentized)

Addresses dotnet#63494

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fickleEfrit
fickleEfrit requested a review from a team as a code owner April 17, 2026 20:05
Copilot AI review requested due to automatic review settings April 17, 2026 20:05
@github-actions github-actions Bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Apr 17, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Apr 17, 2026

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.

Pull request overview

Adds first-class support in the OpenAPI document generator for mapping .NET [Obsolete] metadata to the OpenAPI deprecated: true flag across operations and JSON schemas, reducing the need for custom transformers.

Changes:

  • Mark OpenAPI operations as deprecated when ObsoleteAttribute is present in endpoint metadata.
  • Mark component schemas and inline property schemas as deprecated when the underlying type/property is [Obsolete].
  • Support referenced-property deprecation via a new x-ref-deprecated annotation, plus corresponding parsing and tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs Maps [Obsolete] on types/properties to schema-level deprecated or to a ref-specific annotation for componentized properties.
src/OpenApi/src/Services/OpenApiDocumentService.cs Sets OpenApiOperation.Deprecated based on ObsoleteAttribute in endpoint metadata.
src/OpenApi/src/Services/OpenApiConstants.cs Adds x-ref-deprecated constant for ref-only schema deprecation.
src/OpenApi/src/Schemas/OpenApiSchemaKeywords.cs Adds the deprecated JSON schema keyword constant.
src/OpenApi/src/Schemas/OpenApiJsonSchema.Helpers.cs Parses deprecated and x-ref-deprecated when reading schema JSON into OpenApiSchema.
src/OpenApi/src/Extensions/OpenApiDocumentExtensions.cs Propagates x-ref-deprecated metadata onto OpenApiSchemaReference.Deprecated.
src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.Annotations.cs Adds tests for type/property deprecation (inline + referenced).
src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiDocumentService/OpenApiDocumentServiceTests.Operations.cs Adds tests for operation deprecation via attribute, metadata, and MVC action attribute.

Comment thread src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs Outdated
Comment thread src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs
Comment thread src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs
@fickleEfrit

Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree company="Microsoft"

Avoid calling GetCustomAttributes(inherit: false) twice on the same
type by caching the result in a local variable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@martincostello martincostello added feature-openapi area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically labels Apr 17, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Apr 25, 2026

@mikekistler mikekistler left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good to me! 👍

But I'll defer to the eng team on the details.

@mikekistler
mikekistler requested a review from a team June 2, 2026 17:16
…penapi

# Conflicts:
#	src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs
Comment on lines +115 to +118
if (typeAttributes.OfType<ObsoleteAttribute>().Any())
{
schema[OpenApiSchemaKeywords.DeprecatedKeyword] = true;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This part here might not be needed when we get dotnet/runtime#130665, I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looks like both PRs are for the same thing, unless I'm misreading?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, didn't realize that one was in the runtime instead.

Comment on lines +137 to +140
if (propertyAttributes.OfType<ObsoleteAttribute>().Any())
{
schema[OpenApiSchemaKeywords.DeprecatedKeyword] = true;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here, I think this won't be needed when dotnet/runtime#130665 gets in.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do you know when that will be merged? This PR has been open since April, so not sure if the right move is to merge now and then remove this if it becomes redundant or just wait further.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The PR was opened this week. It's merged now, so hopefully in couple of days or something we will get an updated runtime here with this change.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Apologies, by "this PR" I was referring to the current one, #66355. I know the one you linked is recent :)

I guess we need to wait for the runtime version specified in the aspnetcore deps to be bumped to a version with your PR changes and then remove the now-duplicate logic updating the schema?

Is the runtime version an automatic or manual change?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@fickleEfrit Oh sorry. I thought you had doubts about when the dotnet/runtime PR will get merged.

The version update is automatic. There are automatic pipelines and insertions that will flow the dotnet/runtime changes to dotnet/dotnet repo (known as VMR - Virtual Mono Repo). And once a new full .NET SDK is built from dotnet/dotnet, we get an insertion PR here that updates to that. Usually it doesn't take long.

Meanwhile, could you address the test improvements please so that the tests show the full document?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep, pushed!

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

Copilot-Session: 76a02683-9c07-4c55-bb01-9b0cefc90bb0
@Youssef1313 Youssef1313 self-assigned this Jul 22, 2026
}

[Fact]
public async Task SchemaDeprecated_HandlesObsoletePropertyWithSchemaReference()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm realizing that I might haven't got this test case correctly in the implementation I did in STJ, which I'm going to revisit.

I'm going to merge as-is for now but we should remember to clean up the implementation once the STJ change (potentially with a follow-up fix) flows.

@Youssef1313
Youssef1313 merged commit ac660ce into dotnet:main Jul 22, 2026
24 checks passed
@Youssef1313

Copy link
Copy Markdown
Member

/backport to release/11.0-preview7

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0-preview7 (link to workflow run)

@dotnet dotnet deleted a comment from github-actions Bot Jul 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@Youssef1313 backporting to release/11.0-preview7 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Map [Obsolete] attribute to deprecated in OpenAPI documents
Applying: Cache type-level GetCustomAttributes call
error: sha1 information is lacking or useless (src/OpenApi/src/Services/Schemas/OpenApiSchemaService.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0002 Cache type-level GetCustomAttributes call
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@dotnet dotnet deleted a comment from github-actions Bot Jul 22, 2026
Copilot AI added a commit that referenced this pull request Jul 22, 2026
… documents

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
wtgodbe pushed a commit that referenced this pull request Jul 22, 2026
… documents (#67953)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-rc1 milestone Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc community-contribution Indicates that the PR has been added by a community member feature-openapi pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAPI: Marking Operations, Schemas and Properties as deprecated based on the [Obsolete] attribute

6 participants