You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Swagger UI may not render if code is running using AOT compilation, for example in a Docker container. This is only seen when a 'real' AOT compilation is used.
Replication
To replicate (Visual Studio 2022):
Create a new .Net 8 ASP.NET Core Web API (native AOT), targeting a Docker container
Add Swashbuckle
Run locally (Docker desktop) and access the swagger endpoint (this will work)
Deploy a release build to a container (e.g. Azure Container Instance)
Access the swagger endpoint, and the page will be blank, with an error in the console (typically an javascript undefined or similar error about the config object URLs)
Cause
This is caused by the fact that the SwaggerUIMiddleware creates a JSON serializer that doesn't have any context for the ConfigObject and OAuthConfigObject classes. These are unavailable to the serializer once AOT compilation occurs, so an empty object is written in the javascript configObject object. This then means that the javascript errors when it tries to get the URLs (see the Swashbuckle.AspNetCore.SwaggerUI.index.html resource).
Workaround
With some slightly ugly code, a 'fixed' version of the Swagger UI Middleware can be used:
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace SwaggerFix;
public class SwaggerUIMiddlewareFix : SwaggerUIMiddleware
{
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_jsonSerializerOptions")]
extern static ref JsonSerializerOptions GetJsonSerializerOptions(SwaggerUIMiddleware @this);
[JsonSerializable(typeof(ConfigObject))]
[JsonSerializable(typeof(OAuthConfigObject))]
public partial class SwaggerSerializerContext : JsonSerializerContext { }
public static class SwaggerUIMiddlewareFixExtensions
{
public static IApplicationBuilder UseSwaggerUIFix(this IApplicationBuilder app, Action setupAction = null)
{
SwaggerUIOptions value;
using (IServiceScope serviceScope = app.ApplicationServices.CreateScope())
{
value = serviceScope.ServiceProvider.GetRequiredService<IOptionsSnapshot>().Value;
setupAction?.Invoke(value);
}
if (value.ConfigObject.Urls == null)
{
IWebHostEnvironment requiredService = app.ApplicationServices.GetRequiredService();
value.ConfigObject.Urls = new UrlDescriptor[1]
{
new UrlDescriptor
{
Name = requiredService.ApplicationName + " v1",
Url = "v1/swagger.json"
}
};
}
return app.UseSwaggerUIFix(value);
}
The Swagger UI may not render if code is running using AOT compilation, for example in a Docker container. This is only seen when a 'real' AOT compilation is used.
Replication
To replicate (Visual Studio 2022):
Cause
This is caused by the fact that the SwaggerUIMiddleware creates a JSON serializer that doesn't have any context for the ConfigObject and OAuthConfigObject classes. These are unavailable to the serializer once AOT compilation occurs, so an empty object is written in the javascript configObject object. This then means that the javascript errors when it tries to get the URLs (see the Swashbuckle.AspNetCore.SwaggerUI.index.html resource).
Workaround
With some slightly ugly code, a 'fixed' version of the Swagger UI Middleware can be used:
When this class is used, then the 'fixed' extension should be used instead of the usual UseSwaggerUI extension. e.g.:
app.UseSwagger(); app.UseSwaggerUIFix(o => { o.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"); o.RoutePrefix = string.Empty; });
Versions
Swashbuckle.AspNetCore 6.5.0
.Net 8
The text was updated successfully, but these errors were encountered: