Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft.Extensions.ApiDescription.Server : After build, OpenAPI specification file isn't present in the build result #59334

Open
1 task done
vernou opened this issue Dec 5, 2024 · 11 comments
Labels
area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-openapi

Comments

@vernou
Copy link

vernou commented Dec 5, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I try to follow the documentation Generate OpenAPI documents at build-time, but the OpenAPI specification file isn't present in the build result.

I reproduce on Windows 10 and Windows 11 (I haven't tested it elsewhere).

Expected Behavior

The OpenAPI specification file is in the build result.

Steps To Reproduce

So the script :

dotnet new webapi --name MyApi --no-https --use-program-main --use-controllers
cd MyApi
dotnet add package Microsoft.Extensions.ApiDescription.Server
dotnet build

Then if we display the bin :

> dir bin\Debug\net9.0

 Volume in drive C has no label.
 Volume Serial Number is 60F0-FEC7

 Directory of C:\t\dotnte-poc\MyApi\bin\Debug\net9.0

05/12/2024  15:50    <DIR>          .
05/12/2024  15:50    <DIR>          ..
05/12/2024  15:50               127 appsettings.Development.json
05/12/2024  15:50               151 appsettings.json
29/10/2024  14:30           192 800 Microsoft.AspNetCore.OpenApi.dll
06/08/2024  10:15           239 024 Microsoft.OpenApi.dll
05/12/2024  15:50             2 235 MyApi.deps.json
05/12/2024  15:50             8 704 MyApi.dll
05/12/2024  15:50           145 408 MyApi.exe
05/12/2024  15:50            21 348 MyApi.pdb
05/12/2024  15:50               416 MyApi.runtimeconfig.json
05/12/2024  15:50                68 MyApi.staticwebassets.endpoints.json
              10 File(s)        610 281 bytes
               2 Dir(s)  98 535 710 720 bytes free

The file MyApi.json is missing.


But the file is correctly generated and present in obj :

>dir obj

 Volume in drive C has no label.
 Volume Serial Number is 60F0-FEC7

 Directory of C:\t\dotnte-poc\MyApi\obj

05/12/2024  15:50    <DIR>         .
05/12/2024  15:50    <DIR>         ..
05/12/2024  15:50    <DIR>         Debug
05/12/2024  15:50             2 982  MyApi.csproj.nuget.dgspec.json
05/12/2024  15:50             2 165  MyApi.csproj.nuget.g.props
05/12/2024  15:50               551   MyApi.csproj.nuget.g.targets
05/12/2024  15:50             1 730  MyApi.json                                 <<<<< Here
05/12/2024  15:50                38    MyApi.OpenApiFiles.cache
05/12/2024  15:50            20 520 project.assets.json
05/12/2024  15:50               581   project.nuget.cache
               7 File(s)         28 567 bytes
               3 Dir(s)  98 537 242 624 bytes free

Exceptions (if any)

No response

.NET Version

9.0.101

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Dec 5, 2024
@martincostello
Copy link
Member

I think this is by design that it's in obj (I don't know why though).

There is an MSBuild property you can set to customise where it's written to: OpenApiDocumentsDirectory.

@martincostello martincostello added area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-openapi and removed needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically labels Dec 5, 2024
@vernou
Copy link
Author

vernou commented Dec 5, 2024

The doc says explicitly in the output directory (generally bin) :
Image

So it's the documentation that's wrong?


OpenApiDocumentsDirectory work as expected, but how I can specify the output dir?
It try in csproj :

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <PropertyGroup>
    <OpenApiDocumentsDirectory>$(OutputDir)</OpenApiDocumentsDirectory>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
    <PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="9.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

</Project>

And get the compilation error :

.nuget\packages\microsoft.extensions.apidescription.server\9.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets(55,7): error MSB4184: The expression "[System.IO.Path]::GetFullPath('')" cannot be evaluated. The path is not of a legal form.

@martincostello
Copy link
Member

@vernou
Copy link
Author

vernou commented Dec 5, 2024

I get the same error with OutputPath. I tried also many properties from Common MSBuild project properties

From your example, how is defined ArtifactsPath?

@martincostello
Copy link
Member

It's part of using the Artifacts Output feature: https://learn.microsoft.com/dotnet/core/sdk/artifacts-output

@vernou
Copy link
Author

vernou commented Dec 5, 2024

Ok, thank for your help.

@IsaacCloos
Copy link

I agree that they should update the docs to correctly list where the file is outputted to.

I'm working on a Vue+AspNet template project and here is my property group settings:

<PropertyGroup>
    <OpenApiDocumentsDirectory>../client/src/api</OpenApiDocumentsDirectory>
    <OpenApiGenerateDocumentsOptions>--file-name openapi-schema</OpenApiGenerateDocumentsOptions>
  </PropertyGroup>

A second strange behavior I've found is if you delete this file and rebuild you won't get a new file until you've either changed something about your server code or cleaned your project. I would ideally like to recreate this file if it is missing regardless of the other incremental build optimizations dotnet uses.

@captainsafia
Copy link
Member

I agree that they should update the docs to correctly list where the file is outputted to.

@IsaacCloos Would you be interested in opening a PR on the docs to tweak this? You're correct that the docs are currently incorrect about the default output directory.

A second strange behavior I've found is if you delete this file and rebuild you won't get a new file until you've either changed something about your server code or cleaned your project. I would ideally like to recreate this file if it is missing regardless of the other incremental build optimizations dotnet uses.

Yeah, unfortunately the current strategy is plagued with incrementally issues. :/

This is a good opportunity to dupe this bug report to #58353. The Microsoft.Extensions.ApiDescription.Server implementation predates the OpenAPI support we shipped in .NET 9 and was optimized for use with third-party libraries like Swashbuckle and NSwag. With the new built-in support, we're hoping to reconcile build-time generation into the M.A.OpenApi package and provide a more sensible configuration and execution behavior compared the existing approach.

@captainsafia captainsafia added this to the .NET 10 Planning milestone Dec 17, 2024
@elibroftw
Copy link

elibroftw commented Feb 23, 2025

Can someone explain where this file is? I feel like the mock server isn't even running since the build takes 4 seconds.

<PropertyGroup>
    <OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
    <OpenApiGenerateDocumentsOptions>--file-name openapi-schema</OpenApiGenerateDocumentsOptions>
</PropertyGroup>
...
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="9.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>

Deleted bin and obj dirs

PS C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi> dotnet build                     
Restore complete (1.5s)
  SttApi succeeded (1.5s) → bin\Debug\net9.0\SttApi.dll

Build succeeded in 3.5s
PS C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi> Get-ChildItem openapi-schema.json -Recurse
PS C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi> 
All json file
PS C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi> Get-ChildItem *.json -Recurse             

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\Assets

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-07-23  4:12 PM          49630 countries.json
-a---          2023-09-01 10:03 AM          15539 ExchangeRates.json
-a---          2023-07-19 11:59 PM           4545 getmakes.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\bin\Debug\net9.0\Assets

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-07-23  4:12 PM          49630 countries.json
-a---          2023-09-01 10:03 AM          15539 ExchangeRates.json
-a---          2023-07-19 11:59 PM           4545 getmakes.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\bin\Debug\net9.0

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2025-02-20 12:40 AM            833 appsettings.Development.json
-a---          2025-02-23  4:50 AM           1060 appsettings.json
-a---          2025-02-20 12:16 AM           1302 appsettings.Production.json
-a---          2025-02-23  6:33 PM              3 MvcTestingAppManifest.json
-a---          2025-02-23  6:33 PM         221866 SttApi.deps.json
-a---          2025-02-23  6:33 PM            416 SttApi.runtimeconfig.json
-a---          2025-02-23  6:33 PM          14842 SttApi.staticwebassets.endpoints.json
-a---          2025-02-23  6:33 PM            807 SttApi.staticwebassets.runtime.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\obj\Debug\net9.0

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2025-02-23  6:33 PM              3 MvcTestingAppManifest.json
-a---          2025-02-23  6:33 PM          14842 staticwebassets.build.endpoints.json
-a---          2025-02-23  6:33 PM          20361 staticwebassets.build.json
-a---          2025-02-23  6:33 PM            807 staticwebassets.development.json
-a---          2025-02-23  6:33 PM           1292 staticwebassets.pack.json
-a---          2025-02-23  6:33 PM            179 SttApi.sourcelink.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\obj

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2025-02-23  6:33 PM         334724 project.assets.json
-a---          2025-02-23  6:33 PM           5901 SttApi.csproj.nuget.dgspec.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\Properties\ServiceDependencies\SttApiWindowsAppService - Web Deploy

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2024-03-25 10:14 PM           4381 profile.arm.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi\Properties

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2025-02-20  1:03 AM           1306 launchSettings.json

    Directory: C:\Users\maste\Documents\GitHub\stt-api-backend\SttApi

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2025-02-20 12:40 AM            833 appsettings.Development.json
-a---          2025-02-23  4:50 AM           1060 appsettings.json
-a---          2025-02-20 12:16 AM           1302 appsettings.Production.json

@vernou
Copy link
Author

vernou commented Feb 24, 2025

Ping @elibroftw

So :

dotnet new webapi --name MyApi --no-https --use-program-main --use-controllers
cd MyApi

Modify MyApi.csproj :

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <PropertyGroup>
    <OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
    <OpenApiGenerateDocumentsOptions>--file-name openapi-schema</OpenApiGenerateDocumentsOptions>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.2" />
    <PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="9.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

</Project>

Then :

PS C:\t\MyApi> dotnet build
Restore complete (0.6s)
  MyApi succeeded (1.4s) → bin\Debug\net9.0\MyApi.dll

Build succeeded in 2.7s

PS C:\t\MyApi> Get-ChildItem openapi-schema.json -Recurse


    Directory: C:\t\poc-sss\MyApi


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2/24/2025  10:09 AM           1730 openapi-schema.json

So it's work fine.


Maybe a error in endpoint definition prevents to generate oas.

@elibroftw
Copy link

Hmm okay yeah I should work backwards. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-commandlinetools Includes: Command line tools, dotnet-dev-certs, dotnet-user-jwts, and OpenAPI feature-openapi
Projects
None yet
Development

No branches or pull requests

5 participants