วิธีการตัดเมธอดจากเอกสารประกอบ Swagger บน WebAPI โดยใช้ Swashbuckle


135

ฉันมีโปรแกรม C # ASP.NET WebAPI กับเอกสาร API ถูกสร้างขึ้นโดยอัตโนมัติโดยใช้Swashbuckle ฉันต้องการที่จะละเว้นวิธีการบางอย่างจากเอกสาร แต่ฉันไม่สามารถหาวิธีที่จะบอก Swagger ไม่ให้รวมไว้ในการส่งออก Swagger UI

ฉันรู้สึกว่ามันเป็นสิ่งที่ต้องทำเกี่ยวกับการเพิ่มแบบจำลองหรือตัวกรอง schemaแต่ไม่ชัดเจนว่าจะทำอย่างไรและเอกสารประกอบดูเหมือนจะให้ตัวอย่างของวิธีการปรับเปลี่ยนผลลัพธ์สำหรับวิธีการเท่านั้นไม่เอาออกอย่างสมบูรณ์จากผลลัพธ์

ขอบคุณล่วงหน้า.

คำตอบ:


337

คุณสามารถเพิ่มแอททริบิวต่อไปนี้ไปยังตัวควบคุมและการกระทำเพื่อแยกออกจากเอกสารที่สร้างขึ้น: [ApiExplorerSettings(IgnoreApi = true)]


12
ใช้งานได้ดีนี่ควรเป็นคำตอบ
JohnC

4
มีวิธีการทำโปรแกรมนี้หรือไม่? ฉันต้องการแสดง API ในบางสภาพแวดล้อม แต่ไม่อยู่ในรายการอื่นตามการตั้งค่า
Paul Kienitz

@SyaifulNizamYahya ไม่แน่ใจ อาจจะ [JsonIgnore]?
mikesigs

@mikesigs ใช่งาน [JsonIgnore] น่าเสียดายที่มันไม่ได้ทำให้เป็นอันดับ
Syaiful Nizam Yahya

4
เอกสารประกอบ Swashbuckle:
Omit

17

มีคนโพสต์วิธีแก้ปัญหาบน GitHub ดังนั้นฉันจะวางที่นี่ เครดิตทั้งหมดไปที่เขา https://github.com/domaindrivendev/Swashbuckle/issues/153#issuecomment-213342771

สร้างคลาสแอททริบิวต์ก่อน

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

จากนั้นสร้างคลาสตัวกรองเอกสาร

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);
        }
    }
}

จากนั้นในคลาส Swagger Config ให้เพิ่มตัวกรองเอกสารนั้น

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

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

ขั้นตอนสุดท้ายคือการเพิ่มแอตทริบิวต์ [HideInDocsAttribute] บนตัวควบคุมหรือวิธีที่คุณไม่ต้องการให้ Swashbuckle สร้างเอกสาร


1
ฉันคิดว่า RemoveRoute อาจเป็น Droid ที่ฉันกำลังมองหา
Paul Kienitz

13

คุณสามารถลบ "การดำเนินการ" ออกจากเอกสารที่ซวนเซหลังจากที่มันถูกสร้างขึ้นด้วยตัวกรองเอกสาร - เพียงแค่ตั้งคำกริยาเป็นnull(แม้ว่าอาจมีวิธีอื่นที่จะทำเช่นกัน)

ตัวอย่างต่อไปนี้อนุญาตให้ใช้GETคำกริยาเท่านั้น- และนำมาจากปัญหานี้

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;
        }
    }
}

และในการกำหนดค่าที่กร่างของคุณ:

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

    conf.DocumentFilter<RemoveVerbsFilter>();
});

1
หมายเหตุ: สิ่งนี้จะไม่ลบเส้นทางแม้ว่าคุณจะไม่แสดงความคิดเห็นก็ตามpath.get = null;เนื่องจากเส้นทางเหล่านั้นจะยังคงอยู่ในไฟล์ Swagger แต่จะไม่มีรายละเอียดเท่านั้น อาจเป็นการดีกว่าถ้าApiExplorerSettingsAttributeคุณรวมคำตอบของคุณไว้ในคำตอบเดิมของคุณใน GitHub การใช้ ApiExplorerSettings อาจหลีกเลี่ยงการเพิ่มข้อมูลประเภทลงในschemesรายการไฟล์ Swagger
JBert

7

ฉันต้องการลบรายการพจนานุกรมสำหรับรายการเส้นทางอย่างสมบูรณ์:

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

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

ด้วยวิธีการนี้คุณจะไม่ได้รับรายการ "ว่างเปล่า" ในคำจำกัดความของ swagger.json ที่สร้างขึ้น


3

สร้างตัวกรอง

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);
            }
        }
    }
}

สร้างแอตทริบิวต์

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

ใช้ใน startup.cs

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

เพิ่มแอตทริบิวต์ [SwaggerTag] ให้กับวิธีการและตัวควบคุมที่คุณต้องการรวมไว้ใน Swagger JSON


หวาน. วิธีการที่เหมาะสมและขอบคุณสำหรับการแบ่งปัน sln
Vedran Mandić

2

อาจช่วยใครซักคน แต่ในระหว่างการพัฒนา (การดีบัก) เราต้องการให้ผู้ควบคุมและ / หรือการกระทำทั้งหมดเห็นแล้วซ่อนสิ่งเหล่านี้ระหว่างการผลิต

#if DEBUG
    [ApiExplorerSettings(IgnoreApi = false)]
#else
    [ApiExplorerSettings(IgnoreApi = true)]
#endif  

1

ขึ้นอยู่กับ @spottedmahns คำตอบ งานของฉันคือในทางกลับกัน แสดงเฉพาะรายการที่ได้รับอนุญาต

Frameworks: .NetCore 2.1; กร่าง: 3.0.0

เพิ่มคุณสมบัติ

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

และใช้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);
            }
        }
    }
}

รหัสกำหนดค่าบริการ :

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

    services.AddSwaggerGen(c =>
    {
        // other configurations
        c.DocumentFilter<ShowInSwaggerFilter>();
    });
}

ขอบคุณ Aleha วิธีนี้ใช้ได้ดีกับ SwashBuckle.OData ซึ่ง ApiExplorerSettingsAttribute ใช้งานไม่ได้
Prasad Korhale

1

เพิ่มหนึ่งบรรทัด 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);
}
    }
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.