AspNetCore Swagger for JSON and UI endpoints returning 404

Viewed 653

I am trying to generate my Swagger documentation as per the Microsoft Docs here

Using other answers here and here has not yielded any progress on the issue...

I'm configuring the swagger gen like so:

serviceCollection.AddSwaggerGen(setupAction =>
    {
        setupAction.SwaggerDoc(
            "Open API Specification for Haros v1",
            new OpenApiInfo()
            {
                Title = "Haros API",
                Version = "v1",
                Description = "Haros API Description",
                Contact = new OpenApiContact()
                {
                    Email = "myname@domain",
                    Name = "My Name"
                },
                License = new OpenApiLicense()
                {
                    Name = "MIT License"
                }
            });

        setupAction.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.Http,
            Scheme = "bearer",
            BearerFormat = "JWT",
            Description = "Attach your bearer token in this format to consume the API: Bearer {token}",
        });

        setupAction.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer",
                    },
                }, new List<string>()
            },
        });
    });

And adding the middleware like so:

app.UseSwagger();

app.UseSwaggerUI(setupAction =>
{
   setupAction.SwaggerEndpoint("/swagger/v1/swagger.json", "Haros API v1");
   setupAction.RoutePrefix = string.Empty;
});

Both endpoints (https://localhost:5001/swagger/index.html and https://localhost:5001/swagger/v1/swagger.json) are returning 404.

I've added the option to GenerateDocumentationFile to my project and decorated my API controller endpoint with the /// comments.

What I did notice is that if I comment out the RoutePrefix I manage to load this: Failed to load API definition

I have followed the Microsoft docs link as close as possible, and I don't see anything I potentially missed. Does anyone see what I'm doing wrong or missed?

(additional info: using .NET 5 and loading via Kestrel)

2 Answers

I figured the issue, quite obscure if you ask me. Anyway, this StackOverflow answer helped me and was basically my issue.

When adding your SwaggerGen, the first parameter name

setupAction.SwaggerDoc(
    "Open API Specification for Haros v1", //... etc
)

slots into the URL for the generated documentation at the middleware part here:

setupAction.SwaggerEndpoint("/swagger/<from swagger doc name parameter>/swagger.json", "Haros API v1");

If you do this:

setupAction.SwaggerDoc(
            "v1", //... etc
)

And doing this:

setupAction.SwaggerEndpoint("/swagger/v1/swagger.json", "Haros API v1");

Swagger will load successfully on both endpoints (https://localhost:5001/swagger/index.html and https://localhost:5001/swagger/v1/swagger.json)

Could you chage to SecuritySchemeType.ApiKey?

 services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1",
                new OpenApiInfo
                {
                    Version = "v1",
                    Title = "My API",
                    Description = "My API",
                    Contact = new OpenApiContact
                    {
                        Name = "User",
                        Email = string.Empty,
                        Url = new Uri("https://github.com"),
                    }
                });

            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "Ex: Bearer {token here}",
                Name = "Authorization",
                Scheme = "Bearer",
                BearerFormat = "JWT",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
            });

            c.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference {Type = ReferenceType.SecurityScheme, Id = "Bearer"}
                    },
                    new string[] { }
                }
            });
        });
Related