Swashbuckle.AspNetCore icon indicating copy to clipboard operation
Swashbuckle.AspNetCore copied to clipboard

`SwaggerUIMiddleware` is broken when used with .NET Native AOT

Open JamesNK opened this issue 1 year ago • 17 comments

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: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/eede4717ebd80d3e31bd06a6cb47b6b387b18500/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs#L121-L131

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.

JamesNK avatar Nov 16 '22 07:11 JamesNK

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

Rubenisme avatar Dec 06 '22 14:12 Rubenisme

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?

VAllens avatar Feb 13 '23 08:02 VAllens

.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 avatar Apr 20 '23 11:04 quality-leftovers

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

quality-leftovers avatar Aug 16 '23 11:08 quality-leftovers

Seems that this is related to https://github.com/dotnet/runtime/issues/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?

VMelnalksnis avatar Sep 24 '23 11:09 VMelnalksnis

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)

quality-leftovers avatar Sep 25 '23 08:09 quality-leftovers

@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

VMelnalksnis avatar Sep 28 '23 04:09 VMelnalksnis

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

davidivkovic avatar Nov 03 '23 05:11 davidivkovic

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

Still, we don't have it, is there any update?

MarshalOfficial avatar Dec 06 '23 12:12 MarshalOfficial

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

HakamFostok avatar Dec 09 '23 11:12 HakamFostok

Any updates on this ?

dragos-stoica-metro avatar Dec 27 '23 11:12 dragos-stoica-metro

I would also love a fix for this.

Carl-Granstrom avatar Dec 29 '23 17:12 Carl-Granstrom

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

wdnijdam avatar Jan 13 '24 14:01 wdnijdam

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

aannenko avatar Jan 21 '24 15:01 aannenko

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

quality-leftovers avatar Feb 06 '24 12:02 quality-leftovers

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

Havunen avatar Mar 05 '24 19:03 Havunen

Any updates? this is a blocker btw

eshvatskyi avatar Mar 21 '24 11:03 eshvatskyi

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

martincostello avatar Apr 14 '24 11:04 martincostello