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

SwaggerUIMiddleware is broken when used with .NET Native AOT #2550

Closed
JamesNK opened this issue Nov 16, 2022 · 17 comments · Fixed by #2800
Closed

SwaggerUIMiddleware is broken when used with .NET Native AOT #2550

JamesNK opened this issue Nov 16, 2022 · 17 comments · Fixed by #2800
Assignees
Labels
aot Relates to native AoT support

Comments

@JamesNK
Copy link
Contributor

JamesNK commented Nov 16, 2022

A .NET 7 app can be published as a native executable by setting <PublishAot>true</PublishAot> in the csproj.

I noticed in my test app that the Swagger UI middleware is broken when native AOT is enabled.

The problem is here:

private IDictionary<string, string> GetIndexArguments()
{
return new Dictionary<string, string>()
{
{ "%(DocumentTitle)", _options.DocumentTitle },
{ "%(HeadContent)", _options.HeadContent },
{ "%(ConfigObject)", JsonSerializer.Serialize(_options.ConfigObject, _jsonSerializerOptions) },
{ "%(OAuthConfigObject)", JsonSerializer.Serialize(_options.OAuthConfigObject, _jsonSerializerOptions) },
{ "%(Interceptors)", JsonSerializer.Serialize(_options.Interceptors) },
};
}

JsonSerializer.Serialize internally attempts to generate dynamic code which isn't compatible with native AOT. It throws an error, and a 500 response is returned to the browser.

A fix could be to update these serializer calls to use System.Text.Json source gen - https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/. There are other serializer usages in Swashbuckle that you should test out.

@Rubenisme
Copy link

Yes, this also happened to us for a trimmed (copyused) application, whereas in .NET 6 this was not an issue.

@VAllens
Copy link

VAllens commented Feb 13, 2023

We have been paying attention to this issue for some time.
Is there any progress?

I think this is an easy problem to solve.
Why hasn't it been fixed?

@quality-leftovers
Copy link

.NET 8 preview 3 has added a Native AOT template for Web APIs (dotnet new api -aot). Would be nice if Swashbuckle worked for these templates.

See: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-3/

@quality-leftovers
Copy link

.NET 8 is nearing release. Wondering if this was considered for an upcoming release

@VMelnalksnis
Copy link

Seems that this is related to dotnet/runtime#92345, and the workaround is adding <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
to the publish project. However, that enables it everything, not only Swashbuckle.

It is recommended to switch source-generated context, however it would be enough to explicitly enable reflection-based serialization - https://learn.microsoft.com/en-us/dotnet/core/compatibility/serialization/7.0/reflection-fallback#use-a-custom-contract-resolver. .NET 8 RC1 has already been released, is there any plan to not break builds with trimming enabled?

@quality-leftovers
Copy link

quality-leftovers commented Sep 25, 2023

I think the JsonSerializerIsReflectionEnabledByDefault is just a workaround for people whose application no longer compiles / starts whe moving from .NET 7 to .NET 8.

The reflection based resolver might still randomly fail when trimming is enabled and I believe it's guaranteed to fail when using Native AOT. So you just end up with a Swashbuckle endpoint that might or might not work after every change in your code or update in the .NET compiler.

I've switched to building an OpenAPI spec file using Swashbackle and not using Swashbuckle in the Release build configuration. See: https://medium.com/@mimme/generate-open-api-specification-for-asp-net-core-projects-on-build-c5789d435ffc (the only thing I did different from the medium article was using a seperate OpenApiSpec build configuration as to not make the Debug build dependent on swagger CLI tool)

@VMelnalksnis
Copy link

@quality-leftovers And how do you handle the Swagger UI? Currently the exception happens in the RespondWithIndexHtml method, so I don't see how using the CLI to generate the spec fixes this issue

@davidivkovic
Copy link

Any updates on this topic? .NET 8 releases next week and we would love to use swagger UI.

@HakamFostok
Copy link

Disclaimer: I am NOT a contributor to this repo
but I can see the PR is ready to be merged but it is not merged yet,
I hope that it will be merged ASAP
Thank you all

@dragos-stoica-metro
Copy link

Any updates on this ?

@Carl-Granstrom
Copy link

I would also love a fix for this.

@wdnijdam
Copy link

Please just add the code generated serializers for the net8 publication of the package to make sure it is trimming and AOT compatible.

@aannenko
Copy link

If it's a dangerous change, can we maybe have something like "6.6.0-beta1" nuget where it's included?

VMelnalksnis added a commit to VMelnalksnis/Gnomeshade that referenced this issue Feb 3, 2024
Reflection based serialization is disabled when running the API outside of tests, see domaindrivendev/Swashbuckle.AspNetCore#2550
@quality-leftovers
Copy link

I get the impression the repo is currently not being maintained.

@VMelnalksnis Maybe I was uncleear. I'm not using swagger UI in the release version anymore.

I'm just generating an OpenAPI yaml now.

In .csproj:

<Configurations>Debug;Release;OpenApiSpec</Configurations>

  <!-- Requires dotnet tool Swashbuckle.AspNetCore.Cli -->
  <Target Name="OpenAPI" AfterTargets="Build" Condition="$(Configuration)=='OpenApiSpec'">
    <Exec Command="dotnet swagger tofile --output ../ConnectionCenterApi.OpenAPI.yaml --yaml $(OutputPath)$(AssemblyName).dll v1" WorkingDirectory="$(ProjectDir)" />
  </Target>

and in the Program.cs something along the lines of

#if DEBUG || OPENAPISPEC
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
#endif

#if DEBUG || OPENAPISPEC
       app.UseSwagger()
       .UseSwaggerUI();
#endif

@Havunen
Copy link

Havunen commented Mar 5, 2024

Can you guys test if DotSwashbuckle solves the issue? Its for .NET 8+ only

@eshvatskyi
Copy link

Any updates? this is a blocker btw

@martincostello martincostello added the help-wanted A change up for grabs for contributions from the community label Apr 14, 2024
@martincostello
Copy link
Collaborator

We can look to address this once #2792 is implemented.

@martincostello martincostello self-assigned this Apr 14, 2024
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue Apr 14, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
@martincostello martincostello added aot Relates to native AoT support and removed help-wanted A change up for grabs for contributions from the community labels Apr 14, 2024
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue Apr 14, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue Apr 16, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue Apr 16, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue Apr 23, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue May 1, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue May 8, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit to martincostello/Swashbuckle.AspNetCore that referenced this issue May 12, 2024
Add support for using SwaggerUI with native AoT.
SwaggerGen still does not support native AoT, though it happens to work for simple cases.
Resolves domaindrivendev#2550.
martincostello added a commit that referenced this issue May 12, 2024
Add support for using SwaggerUI with native AoT.

SwaggerGen still does not support native AoT, though it happens to work for simple cases.

Resolves #2550.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aot Relates to native AoT support
Projects
None yet
15 participants