Frank Mehlhop
Frank Mehlhop

Reputation: 2222

Swagger shows endpoints from other project

I got a solution with few projects. Few of them use (are) Web Api's. There I use Swagger.

At one of the projects (project A) I have only one endpoint. But when I start Swagger, I see also the endpoints of one other project (project B). Other way around I don't see the one endpoint (A) at the Swagger of the (B) project.

The Swagger configurations are similar at both projects.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info
        {
            Title = "My Platform – A",
            Version = "v1",
            Description = "A ~ ASP.NET Core Web API"
        });
    }); // ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("swagger/v1/swagger.json", "A V1");
        c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
        c.RoutePrefix = string.Empty;
    }); // ...
}

How can it be? What I need to change to get only the own endpoint(-s)?

Upvotes: 1

Views: 2710

Answers (2)

pizzaboy
pizzaboy

Reputation: 1043

despite the first answer being the cleanest way to deal with this problem, there's actually something more you can do about it. You can filter which controller you want to display based on some arbitrary criteria. Here's the ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "Swagger API", Version = "v1" });
        c.DocumentFilter<SwaggerDocumentFilter>();
    });
    ...

With the DocumentFilter extension method you can add custom classes implementing the interface IDocumentFilter which allow you to add logic.

In the class SwaggerDocumentFilter you can then specify which controller you want to be hidden from Swagger, by default, all controllers are shown. In the example, all the controllers that do not belong to the Assembly with a namespace like "MyAssemblyNamespace...", will be hidden:

internal class SwaggerDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var apiDescription in context.ApiDescriptions)
        {
            var controllerActionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor;

            // If the namespace of the controller DOES NOT start with..
            if (!controllerActionDescriptor.ControllerTypeInfo.FullName.StartsWith("MyAssemblyNamespace"))
             {
                var key = "/" + apiDescription.RelativePath.TrimEnd('/');
                swaggerDoc.Paths.Remove(key); // Hides the Api
            }
        }
    }
}

Note that the Apply function of the SwaggerDocumentFilter class is executed for every time you open the Swagger page(or invoke it's internal API).

Upvotes: 0

Frank Mehlhop
Frank Mehlhop

Reputation: 2222

The solution was that project A uses a class from project B. This class need to be at the common business project. So I removed the class and the dependency. Now every thing works fine.

Upvotes: 3

Related Questions