Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue Using Custom Index.Html in Swagger / Swashbuckle for .NET Core

I am having difficulty using a custom index.html and other assets with swashbuckle. Swashbuckle/Swagger do not seem to recognizing or using them at all. I do have app.UseDefaultFiles() and app.UseStaticFiles() set. I am trying to understand what I am doing incorrectly.

I have attempted to set up my configuration somewhat similar to what is defined on the Microsoft article without success. (https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio)

I am presently using the files from the dist folder referenced in the article (https://github.com/swagger-api/swagger-ui/tree/2.x/dist) along with the custom css file provided.

My index.html file is located under /wwwroot/swagger/ui The custom css file is located under /wwwroot/swagger/ui/css (as custom.css)

Here is my Startup.cs class.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
             .AddJsonOptions(options =>
             {
                 // Swagger - Format JSON
                 options.SerializerSettings.Formatting = Formatting.Indented;
             });

        // Register the Swagger generator, defining one or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.DescribeAllEnumsAsStrings();
            c.DescribeStringEnumsInCamelCase();
            // c.DescribeAllParametersInCamelCase();                

            c.SwaggerDoc("v1",
                new Info
                {
                    Title = "My Web API - v1",
                    Version = "v1",
                    Description = "New and improved version. A simple example ASP.NET Core Web API. "

                }
            );

            c.SwaggerDoc("v2",
                new Info
                {
                    Title = "My Web API - v2",
                    Version = "v2",
                    Description = "New and improved version. A simple example ASP.NET Core Web API. "
                }
            );

            // Set the comments path for the Swagger JSON and UI.
            var basePath = AppContext.BaseDirectory;
            var xmlPath = Path.Combine(basePath, "ApiTest.xml");
            c.IncludeXmlComments(xmlPath);
        });

    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        string swaggerUIFilesPath = env.WebRootPath + "\\swagger\\ui";

        if (!string.IsNullOrEmpty(swaggerUIFilesPath))
        {
            app.UseDefaultFiles();
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(swaggerUIFilesPath),
                RequestPath = new PathString("/api-docs"),
            });
        }

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger(c =>
        {
            c.RouteTemplate = "api-docs/{documentName}/swagger.json";
        });

        // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            //c.ShowJsonEditor();
            c.RoutePrefix = "api-docs";
            c.SwaggerEndpoint("/api-docs/v1/swagger.json", "My Web API - V1 ");
            c.SwaggerEndpoint("/api-docs/v2/swagger.json", "My Web API - V2 ");
            c.DocumentTitle("My Web API");
        });

        app.UseMvc();
    }
}

My ultimate objective is to be able to use something like the slate style theme available here (https://github.com/omnifone/slate-swagger-ui). For right now, I am just trying to get Swashbuckle/Swagger to use the customized files referenced in the Microsoft documentation before trying to make the other files work.

I really do NOT want to try and convert my assets to embedded resources--since there will many of them. I just want to reference a normal index.html file and be able to use all of its referenced files.

What am I doing wrong?

Relevant Software Versions

  • .Net Core Version: 2.0.3
  • Swashbuckle.AspNetCore: 1.2.0
  • Windows 10 Enterprise Build 1703
  • Visual Studio 2017 Enterprise 15.5.2
like image 504
Anthony Gatlin Avatar asked Mar 01 '18 14:03

Anthony Gatlin


People also ask

What is Swashbuckle in ASP NET Core?

The NuGet package Swashbuckle provides the implementation of Swagger or OpenAPI Specification in .Net. For ASP.Net Core, we will add the NuGet package Swashbuckle.AspNetCore in our project. At the time of writing this blog, the version of Swashbuckle.AspNetCore is 5.4.0.

How to implement Swagger in ASP NET Core?

For implementing swagger in ASP.Net Core, first, we will create a new project. For creating a new ASP.Net Core Web API, I will open Visual Studio 2019. Once Visual Studio is open, I will select the menu option File -> New -> Project. Once the new project creation window pops up, I will select the ASP.Net Core Web Application.

Why use swagger and Swashbuckle for API documentation?

Many of us use Swagger and Swashbuckle to document our APIs in C #. They are very easy to use, to the point that they are already included in the webapi base template project. Thanks to this, we can reduce the time we spend documenting a service.

What version of Swashbuckle is used with NuGet?

At the time of writing this blog, the version of Swashbuckle.AspNetCore is 5.4.0. Once we add the NuGet package to the project, we will configure Swagger inside the project.


2 Answers

Here is the minimum action I found to be necessary to replace SwashBuckle's index.html in a .NET Core project:

  • Get a copy of the original index.html from here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/index.html

  • Place that copy in some sub-folder of your project.
    The file may have a different name, I chose: \Resources\Swagger_Custom_index.html

  • Right-click that file in Solution Explorer, select 'Properties', select 'Configuration Properties' in left pane. Under 'Advanced' in right pane find entry 'Build Action' and set it to 'Embedded resource'. Click Ok.

  • In Startup.cs add the following line to your app.UseSwaggerUI() call:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
    
        app.UseSwaggerUI(c =>
        {
            c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Your.Default.Namespace.Resources.Swagger_Custom_index.html");
        });
    
        //...
    }
    
  • The identifier for the file resource in the above GetManifestResourceStream method is composed of:

    1. your default namespace (i.e. 'Your.Default.Namespace')
    2. the sub-path of your resource (i.e. 'Resources')
    3. the filename of your resource (i.e. 'Swagger_Custom_index.html')

    All three parts are concatenated using dots (NO slashes or backslashes here).
    If you don't use a sub-path but have your resource in root, just omit part 2.

like image 141
Jpsy Avatar answered Sep 17 '22 19:09

Jpsy


For people who separate ApplicationBuilder config methods on ASP.NET Core:

If the separated method/class is static, it is not possible to call GetType() because an object reference is required.

In that case, switch GetType() to MethodBase.GetCurrentMethod().DeclaringType

c.IndexStream = () => MethodBase.GetCurrentMethod().DeclaringType.Assembly.GetManifestResourceStream("xxx.index.html");
like image 24
Fieldwing Avatar answered Sep 19 '22 19:09

Fieldwing