Reputation: 2420
I wanted to customize the swagger UI using my own custom design. I have the following configuration in a startup.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSwaggerGen(c =>
{
c.DocumentFilter<DescriptionsDocumentFilter>();
c.SwaggerDoc("v1", new OpenApiInfo { Title = "LoggerDemo", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
services.AddHttpClient();
services.AddMemoryCache();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger(o =>
{
o.RouteTemplate = "docs/{documentName}/docs.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "docs";
c.SwaggerEndpoint("/docs/v1/docs.json", "Geo API");
c.IndexStream = () => GetType().Assembly.GetManifestResourceStream
(
GetType().Namespace + ".Resources.Swagger_Custom_index.html"
);
});
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Here are the steps I have followed:
I have got a copy of the original index.html from here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/index.html
Created the folder Resources
and placed the file name Swagger_Custom_index.html
in the Resources folder
Configure
in startup.cs:app.UseSwaggerUI(c =>
{
c.IndexStream = () => GetType().Assembly.GetManifestResourceStream
(
GetType().Namespace + ".Resources.Swagger_Custom_index.html"
);
});
But I am struggling to access the custom HTML file, How to access the custom HTML file? What URL should I use to access those files?
Upvotes: 2
Views: 13842
Reputation: 11101
You need to embed the HTML file in the DLL with an EmbeddedResource
directive in your .csproj
file:
Resources/swagger.html
<!-- replace this with the actual swagger.html -->
<h1>hello swagger</h1>
.csproj
<Project Sdk="Microsoft.NET.Sdk">
<!-- ... -->
<ItemGroup>
<Content Remove="Resources\*" />
<EmbeddedResource Include="Resources\*" />
</ItemGroup>
</Project>
Then you can access it with Assembly.GetManifestResourceStream
:
// Startup.Configure
app.UseSwaggerUI(options =>
{
options.IndexStream = () => GetType().Assembly.GetManifestResourceStream($"{GetType().Namespace}.Resources.swagger.html");
});
SwaggerMiddleware handles serving OpenAPI documents. We can use that as reference to build the document ourselves.
First register SwaggerGenerator
with DI:
// Startup.Configure
services.AddTransient<SwaggerGenerator>();
Then inject it inside a class, here I'm using an endpoint to serve it directly:
// Startup.Configure
app.UseEndpoints(e =>
{
// ...
e.MapGet("/openapi.json", context =>
{
// inject SwaggerGenerator
var swaggerGenerator = context.RequestServices.GetRequiredService<SwaggerGenerator>();
// document name is defined in Startup.ConfigureServices method inside the AddSwaggerGen call
var doc = swaggerGenerator.GetSwagger("v1");
// serialize the document as json
using var writer = new StringWriter(CultureInfo.InvariantCulture);
var serializer = new OpenApiJsonWriter(writer);
doc.SerializeAsV3(serializer);
var json = writer.ToString(); // this is the openapi document
// serve it as json
context.Response.ContentType = MediaTypeNames.Application.Json;
return context.Response.WriteAsync(json, new UTF8Encoding(false));
});
});
Upvotes: 2