Search code examples
.netasp.net-coreswaggerasp.net-core-webapiswagger-ui

.NET Core 3.1 Swagger issues with IIS


Situation:

I have a .NET Core 3.1 web API. I want to host it on IIS on a server. In IIS I have a main site and I want the API to be hosted UNDER the site. e.g.

  • Site1
    • Api

The address would be, e.g. https://site1/api

Now, for some reason, I cannot for the life of me get swagger working properly. I am using the Swashbuckle.AspNetCore NuGet.

Server

I have installed the asp.net core hosting bundle, IIS is configured and I can access the site.

ConfigureServices()

enter image description here

Configure()

enter image description here

IIS

2 app pools:

  • first one for main site, .NET CLR v4.0, Integrated Pipeline
  • second one for web API, No Managed Code, Integrated Pipeline

Now, I have done this a million times like in the Configure() example, but it just does not want to work.

I am trying different things, but am getting a mixture of errors, such as:

  • index.html throws error "response status is 404 /swagger/v1/swagger.json", but the .json URL exists
  • index.html throws error "undefined /swagger/v1/swagger.json", but the .json URL exists

etc...

I have tried many solutions, such as:

  • using relating path in SwaggerEndpoint - does not work, the path just shows up as a literal string
  • setting RouteTemplate in app.UseSwagger() - I NEVER had to do this, but still, it doesn't work
  • Tried to change default swagger route - I tried this locally while also changing launchSettings.json launchUrl to "api". I can access swagger.json file, but index.html gives me a 404 error
  • As per Microsoft documentation, "If using directories with IIS or a reverse proxy, set the Swagger endpoint to a relative path using the ./ prefix. For example, ./swagger/v1/swagger.json."

If I do this and also change the launchSettings.json launchUrl to "api", then locally everything is fine, altho the hyperlink in Swagger UI is broken.

enter image description here

If I publish this change to IIS, then neither swagger.json, nor index.html is shown, I get a 404 error.

I have hosted web APIs like this a dozen times and the ONLY thing I ever needed to do was change the swagger endpoint, but for some reason it's not working this time.

I appreciate any help.

What I also tried

I am trying these situations with launchSettings.json launchUrl set to "api"

#1

var swaggerEndpoint = "/swagger/v1/swagger.json";
var routePrefix = "api";

Locally:

http://localhost:50473/api/index.html gets loaded, BUT swagger.json gets generated under root folder (http://localhost:50473/swagger/v1/swagger.json)

In IIS: index.html does not get loaded, but swagger.json gets generated correctly (api/swagger/v1/swagger.json)

#2

var swaggerEndpoint = "swagger/v1/swagger.json";
var routePrefix = "api";

app.UseSwagger(c =>
{
    c.RouteTemplate = "api/swagger/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint(swaggerEndpoint, "Loyalty API");
    c.RoutePrefix = routePrefix;
});

This time I set the RouteTemplate and changed swaggerEndpoints.

Locally:

index.html gets loaded, swagger.json gets generated under the /api url (http://localhost:50473/api/swagger/v1/swagger.json), altho I'm not sure about the hyperlink, since it shows the full URL

enter image description here

Notice that there is no prefixed forward slash in swaggerEndpoint.

IIS:

This solution does not work when hosted to IIS. Neither index.html is shown, nor swagger.json is generated.


Solution

  • So, I have no idea why, but my original solution works.

    var routePrefix = string.Empty;
    var swaggerEndpoint = "/swagger/v1/swagger.json";
    
    if (env.IsEnvironment("Test"))
    {
        swaggerEndpoint = "/api/swagger/v1/swagger.json";
    }
    
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint(swaggerEndpoint, "Loyalty API");
        c.RoutePrefix = routePrefix;
    });
    

    Either I missed something or my brain is fried. I MIGHT have not set the RoutePrefix when changing the swaggerEndpoint.