Swashbuckle.aspnetcore: 5.0.0-rc2 Cannot read swagger.json error when hosted as an application under a website on IIS

Created on 5 Sep 2019  路  2Comments  路  Source: domaindrivendev/Swashbuckle.AspNetCore

Thanks for contributing to Swashbuckle.AspNetCore! As per the contributing guidelines, please adhere to the following rules of thumb before submitting your issue:

VERSION:

5.0.0-rc2

STEPS TO REPRODUCE:

Create a webapi project in Net Core 2.2 running on IIS.

.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <!-- Enables XML comments on Swagger-UI -->
  <PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
  </ItemGroup>

</Project>

Startup:

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().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                c.RoutePrefix = string.Empty;
            });

            app.UseMvc();
        }
    }

EXPECTED RESULT:

Working on local development as http://localhost:5000/ and on IIS on localhost/mysite/

ACTUAL RESULT:

It works locally and when I compile a release version and deploy to IIS, I enter the site http://localhost/mysite/ and the error:
Fetch error Not Found /swagger/v1/swagger.json

Also, in the browser, if I enter http://localhost/mysite/swagger/v1/swagger.json I see a Json in OpenApi.

WORKAROUND

I got on Stackoverflow a workaround, but I think the lib should really identify the application path by default since I am using the default path for the swagger.json (/swagger/v1/swagger.json)

app.UseSwaggerUI(c =>
        {
#if DEBUG
               // For Debug in Kestrel
               c.SwaggerEndpoint("/swagger/v1/swagger.json", "Web API V1");
#else
               // To deploy on IIS
               c.SwaggerEndpoint("/mysite/swagger/v1/swagger.json", "Web API V1");
#endif
            c.RoutePrefix = string.Empty;
        });

Most helpful comment

AFAIK, it's not possible for an application to reliably _detect_ the virtual path it's hosted under. But please correct me if I'm wrong, and submit a PR 馃槈

However, there's a simpler approach that should work for you - just remove the leading slash when specifying your swagger endpoint so that it's _relative_ to the URL of the swagger-ui (application root in your case):

 c.SwaggerEndpoint("swagger/v1/swagger.json", "Web API V1");

All 2 comments

AFAIK, it's not possible for an application to reliably _detect_ the virtual path it's hosted under. But please correct me if I'm wrong, and submit a PR 馃槈

However, there's a simpler approach that should work for you - just remove the leading slash when specifying your swagger endpoint so that it's _relative_ to the URL of the swagger-ui (application root in your case):

 c.SwaggerEndpoint("swagger/v1/swagger.json", "Web API V1");

In addition to the above, what about c.RoutePrefix? It doesnt work for me locally without setting it to an empty string. With:

c.SwaggerEndpoint("swagger/v1/swagger.json", "EDIPartner V1");
c.RoutePrefix = "";

I still have the "Failed to load API definition" error: Fetch error
Service Unavailable ../swagger/v1/swagger.json

Was this page helpful?
0 / 5 - 0 ratings