Cara menghilangkan metode dari dokumentasi Swagger di WebAPI menggunakan Swashbuckle

135

Saya memiliki aplikasi C # ASP.NET WebAPI dengan dokumentasi API yang dihasilkan secara otomatis menggunakan Swashbuckle . Saya ingin dapat menghilangkan metode tertentu dari dokumentasi tetapi saya tidak bisa menemukan cara untuk memberitahu Swagger untuk tidak memasukkan mereka dalam output UI Swagger.

Saya rasa itu ada hubungannya dengan menambahkan model atau skema filter tetapi tidak jelas apa yang harus dilakukan dan dokumentasi hanya tampaknya memberikan contoh bagaimana memodifikasi output untuk suatu metode, tidak menghapusnya sepenuhnya dari output.

Terima kasih sebelumnya.

SteveWilkinson
sumber

Jawaban:

337

Anda dapat menambahkan atribut berikut ke Pengontrol dan Tindakan untuk mengeluarkannya dari dokumentasi yang dibuat: [ApiExplorerSettings(IgnoreApi = true)]

mikesigs
sumber
12
Berhasil, ini seharusnya jawabannya
JohnC
4
Apakah ada cara untuk melakukan ini secara terprogram? Saya ingin mengekspos API di beberapa lingkungan tetapi tidak di yang lain, sesuai dengan pengaturan konfigurasi.
Paul Kienitz
@SyaifulNizamYahya Tidak yakin. Mungkin [JsonIgnore]?
mikesigs
@mikesigs Ya [JsonIgnore] bekerja. Sayangnya, itu melarang serialisasi.
Syaiful Nizam Yahya
4
Dokumentasi Swashbuckle: Abaikan Operasi Sewenang-wenang
spottedmahn
17

Seseorang memposting solusinya di github jadi saya akan menempelkannya di sini. Semua kredit jatuh padanya. https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

Buat dulu kelas atribut

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class HideInDocsAttribute : Attribute
{
}

Kemudian buat kelas Filter Dokumen

public class HideInDocsFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (var apiDescription in apiExplorer.ApiDescriptions)
        {
            if (!apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<HideInDocsAttribute>().Any() && !apiDescription.ActionDescriptor.GetCustomAttributes<HideInDocsAttribute>().Any()) continue;
            var route = "/" + apiDescription.Route.RouteTemplate.TrimEnd('/');
            swaggerDoc.paths.Remove(route);
        }
    }
}

Kemudian di kelas Konfigurasi Sombong, tambahkan filter dokumen itu

public class SwaggerConfig
{
    public static void Register(HttpConfiguration config)
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        config
             .EnableSwagger(c =>
                {
                    ...                       
                    c.DocumentFilter<HideInDocsFilter>();
                    ...
                })
            .EnableSwaggerUi(c =>
                {
                    ...
                });
    }
}

Langkah terakhir adalah menambahkan atribut [HideInDocsAttribute] pada Controller atau Metode yang Anda tidak ingin Swashbuckle membuat dokumentasi.

Paulo Pozeti
sumber
1
Saya pikir RemoveRoute mungkin adalah droid yang saya cari.
Paul Kienitz
13

Anda dapat menghapus "operasi" dari dokumen kesombongan setelah dibuat dengan filter dokumen - cukup setel kata kerjanya ke null(meskipun, mungkin ada cara lain untuk melakukannya juga)

Sampel berikut hanya memungkinkan GETkata kerja - dan diambil dari masalah ini .

class RemoveVerbsFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        foreach (PathItem path in swaggerDoc.paths.Values)
        {
            path.delete = null;
            //path.get = null; // leaving GET in
            path.head = null;
            path.options = null;
            path.patch = null;
            path.post = null;
            path.put = null;
        }
    }
}

dan dalam konfigurasi kesombongan Anda:

...EnableSwagger(conf => 
{
    // ...

    conf.DocumentFilter<RemoveVerbsFilter>();
});
Dave Transom
sumber
1
Perhatikan: ini tidak akan menghapus path meskipun Anda membatalkan komentar path.get = null;- sebagai hasilnya path tersebut akan tetap disertakan dalam file Swagger tetapi hanya tanpa perincian. Mungkin lebih baik untuk memasukkan ApiExplorerSettingsAttributejawaban Anda seperti yang Anda sebutkan di balasan asli Anda di GitHub. Menggunakan ApiExplorerSettings juga dapat menghindari mengetikkan informasi agar tidak ditambahkan ke daftar file Swagger schemes.
JBert
7

Saya lebih suka menghapus entri kamus untuk item jalur sepenuhnya:

var pathsToRemove = swaggerDoc.Paths
                .Where(pathItem => !pathItem.Key.Contains("api/"))
                .ToList();

foreach (var item in pathsToRemove)
{
    swaggerDoc.Paths.Remove(item.Key);
}

Dengan pendekatan ini, Anda tidak akan mendapatkan item "kosong" dalam definisi swagger.json yang dihasilkan.

Denis Biondic
sumber
3

Buat filter

public class SwaggerTagFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach(var contextApiDescription in context.ApiDescriptions)
        {
            var actionDescriptor = (ControllerActionDescriptor)contextApiDescription.ActionDescriptor;

    if(!actionDescriptor.ControllerTypeInfo.GetCustomAttributes<SwaggerTagAttribute>().Any() && 
    !actionDescriptor.MethodInfo.GetCustomAttributes<SwaggerTagAttribute>().Any())
            {
                var key = "/" + contextApiDescription.RelativePath.TrimEnd('/');
            swaggerDoc.Paths.Remove(key);
            }
        }
    }
}

Buat atribut

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class SwaggerTagAttribute : Attribute
{
}

Terapkan di startup.cs

 services.AddSwaggerGen(c => {
            c.SwaggerDoc(1,
                new Info { Title = "API_NAME", Version = "API_VERSION" });
            c.DocumentFilter<SwaggerTagFilter>(); // [SwaggerTag]
        });

Tambahkan atribut [SwaggerTag] ke metode dan pengontrol yang ingin Anda sertakan dalam Swagger JSON

Rowan Stringer
sumber
Manis. Pendekatan yang tepat dan terima kasih telah berbagi SLN.
Vedran Mandić
2

Dapat membantu seseorang tetapi selama pengembangan (debugging) kami ingin mengekspos seluruh Pengendali dan / atau Tindakan dan kemudian menyembunyikan ini selama produksi (rilis rilis)

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  
Soeren Pedersen
sumber
1

Berdasarkan jawaban @spottedmahns . Tugas saya adalah sebaliknya. Tampilkan hanya yang diizinkan.

Kerangka Kerja: .NetCore 2.1; Sombong: 3.0.0

Atribut ditambahkan

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class ShowInSwaggerAttribute : Attribute
{
}

Dan mengimplementasikan custom IDocumentFilter

public class ShowInSwaggerFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {

        foreach (var contextApiDescription in context.ApiDescriptions)
        {
            var actionDescriptor = (ControllerActionDescriptor) contextApiDescription.ActionDescriptor;

            if (actionDescriptor.ControllerTypeInfo.GetCustomAttributes<ShowInSwaggerAttribute>().Any() ||
                actionDescriptor.MethodInfo.GetCustomAttributes<ShowInSwaggerAttribute>().Any())
            {
                continue;
            }
            else
            {
                var key = "/" + contextApiDescription.RelativePath.TrimEnd('/');
                var pathItem = swaggerDoc.Paths[key];
                if(pathItem == null)
                    continue;

                switch (contextApiDescription.HttpMethod.ToUpper())
                {
                    case "GET":
                        pathItem.Get = null;
                        break;
                    case "POST":
                        pathItem.Post = null;
                        break;
                    case "PUT":
                        pathItem.Put = null;
                        break;
                    case "DELETE":
                        pathItem.Delete = null;
                        break;
                }

                if (pathItem.Get == null  // ignore other methods
                    && pathItem.Post == null 
                    && pathItem.Put == null 
                    && pathItem.Delete == null)
                    swaggerDoc.Paths.Remove(key);
            }
        }
    }
}

Kode Konfigurasi Layanan :

public void ConfigureServices(IServiceCollection services)
{
     // other code

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}
aleha
sumber
Terima kasih Aleha. Pendekatan ini sebenarnya bekerja dengan baik untuk SwashBuckle.OData di mana ApiExplorerSettingsAttribute tidak berfungsi.
Prasad Korhale
1

tambahkan satu baris SwaggerConfig c.DocumentFilter ();

public class HideInDocsFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        { 
var pathsToRemove = swaggerDoc.Paths
                .Where(pathItem => !pathItem.Key.Contains("api/"))
                .ToList();

foreach (var item in pathsToRemove)
{
    swaggerDoc.Paths.Remove(item.Key);
}
    }
}
Vikramraj
sumber
0

Tambahkan ini di atas Metode Anda yang ingin Anda hilangkan-

[ApiExplorerSettings(IgnoreApi=true)]
Mridusmita Deka
sumber