domaindrivendev/Swashbuckle.AspNetCore

注意早期使用者,请注意,这个package已经被命名为Swashbuckle.AspNetCore
如果你一直使用Swashbuckle 对于AspNetCore直到他创建以来。你可能会引用"Swashbuckle.6.0.0-beta*" packages,这些都不再有效了,最初的意图是移动Swashbuckle project从ASP.NET Web API到ASP.NET Core,现在微软计划支持WebApi至少四年了,我觉得把它分成几个单独的项目比较合适,允许两者都使用各自的框架。尽管如此,我个人还会把部分时间花在这个版本上。

Swashbuckle.AspNetCore

Build status

Swagger 使用Asp.net core 建立API.生成漂亮的API.包含一个UI的探索和测试操作。直接从你的routes, controllers and models.

In addition to its Swagger generator。Swashbuckle 还提供了一个嵌入式很厉害的版本swagger-ui that's powered by the generated Swagger JSON。这意味着您可以使用与最新代码同步的活文档来补充您的 API,最重要的是,它需要最少的编码和维护,使得您能够专注于构建一个令人敬畏的的API.

And that's not all ...

一旦你有了一个可以自我吹嘘的API.您已经打开了基于傲慢的工具的宝库,其中包括一个客户端生成器,它可以针对广泛的流行平台作为使用。See swagger-codegen for more details.

Getting Started

  1. Install the standard Nuget package into your ASP.NET Core application.

    Install-Package Swashbuckle.AspNetCore
    
  2. In the ConfigureServices method of Startup.cs, register the Swagger generator, defining one or more Swagger documents.

    services.AddMvc();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
    });
  1. Ensure your API actions and non-route parameters are decorated with explicit "Http" and "From" bindings.
   [HttpPost]
   public void Create([FromBody]Product product)
   ...

   [HttpGet]
   public IEnumerable Search([FromQuery]string keywords)
   ...

NOTE: If you omit the explicit parameter bindings, the generator will describe them as "query" params by default.

  1. In the Configure method, insert middleware to expose the generated Swagger as JSON endpoint(s)
    app.UseSwagger();

在这个点上,你可以开启你的应用程序,并查看生成的swagger json 在 "/swagger/v1/swagger.json."_

  1. 如果你想要公开交互式文档,指定swagger jsonl来提供程序,你可以插入一个 swagger-ui middleware。
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

现在你可以重新启动你的应用程序,并且选择自动生成,交互式文档在"/swagger"._

Swashbuckle, ApiExplorer, and Routing

Swashbuckle 严重依赖on ApiExplorer,the API metadata layer that ships with ASP.NET Core,如果您正在使用AddMvc帮助器引导MVC堆栈,然后,ApiExplorer将会自动注册,并且不会出现问题。但是,如果您正在使用AddMvcCore作为一个更有付费功能的MVC栈,您需要显式地添加Api资源管理器服务:

services.AddMvcCore()
    .AddApiExplorer();

实际上,如果你使用conventional routing(与属性路由相反),任何控制器和使用常规路由的控制器的操作都不会在ApiExplorer中表示,which means Swashbuckle won't be able to find those controllers and generate Swagger documents from them. For instance:

app.UseMvc(routes =>
{
   // SwaggerGen won't find controllers that are routed via this technique.
   routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

You must use attribute routing for any controllers that you want represented in your Swagger document(s):

[Route("example")]
public class ExampleController : Controller
{
    [HttpGet("")]
    public IActionResult DoStuff() { /**/ }
}

Refer to the routing documentation for more information.

Components(组件)

Swashbuckle由三个包组成,作为一个swagger的生成器,中间件将生成的swagger-ui作为JSON端点和中间件暴露出来,从而暴露出由这些端点提供的强大的用户界面。他们能被一起安装,via the "Swashbuckle.AspNetCore" meta-package,或者根据你的具体要求独立自主,更多细节请参见下面的表格.

Package Description
Swashbuckle.AspNetCore.Swagger 暴露SwaggerDocument objects作为一个JSON API.它将提供一个实现 ISwaggerProvider 能去注册,查询检索Swagger document(s) 在返回序列号Json之前。
Swashbuckle.AspNetCore.SwaggerGen 注入一个ISwaggerProvider 的实现可以能被使用通过上述组件使用。这个特定的实现会通过你的routes,controllers,和models自动生成 SwaggerDocument(s) .
Swashbuckle.AspNetCore.SwaggerUI 公开一个嵌入式版本的大用户界面,你指定了API端点,它可以获取Swagger Json并使用它们为API提供交互式文档。

Configuration(配置) & Customization(用户化)

上面描述的步骤将使您启动并运行最少的设置
然而,Swashbuckle 在您认为合适的情况下,提供了很多定制的灵活性。下面的表格列出了所有的选项。

  • Swashbuckle.AspNetCore.Swagger

    • Change the Path for Swagger JSON Endpoints 改变Swagger JSON Endpoints的路径。
    • Modify Swagger with Request Context使用Request Context修改Swagger.
  • Swashbuckle.AspNetCore.SwaggerGen

  • List Operations Responses列表操作响应

    • Include Descriptions from XML Comments 包括来自XML注释的描述。
    • Provide Global API Metadata提供全球API元数据
    • Generate Multiple Swagger Documents生成多个Swagger 文档
    • Omit Obsolete Operations and/or Schema Properties省略已过时的操作和/或模式属性。
    • Omit Arbitrary Operations省略任意操作。
    • Customize Operation Tags (e.g. for UI Grouping)自定义操作标签。
    • Change Operation Sort Order (e.g. for UI Sorting)更改操作排序顺序(例如,用于UI排序)
    • Customize Schema Id's定义模式Id's
    • Customize Schema for Enum Types用于枚举类型的自定义模式。
    • Override Schema for Specific Types针对特定类型的覆盖模式。
    • Extend Generator with Operation, Schema & Document Filters使用生成操作,模式和文档过滤器扩展生成器。
    • Add Security Definitions and Requirements添加安全性定义和需求。
  • Swashbuckle.AspNetCore.SwaggerUI

    • Change Releative Path to the UI 更改用户界面的发布地址
    • Change Document Title更改文件标题
    • List Multiple Swagger Documents 多个Swagger文档。
    • Apply swagger-ui Parameters 应用swagger-ui 参数
    • Inject Custom CSS注入自定义的CSS.
    • Enable OAuth2.0 Flows开启OAuth 2.0 授权流。

Swashbuckle.AspNetCore.Swagger

Change the Path for Swagger JSON Endpoints(改变Path对于Swagger JSON)

默认情况下,Swagger JSON将被公开在以下 route-"/swagger/{documentName}/swagger.json",如果有必要,你可以改变它当启用了Swagger中间件。自定义的路由将包含 {documentName} 参数。

app.UseSwagger(c =>
{
    c.RouteTemplate = "api-docs/{documentName}/swagger.json";
});

注意:如果你使用SwaggerUI中间件,你讲需要去更新configuration反映新的点:

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/api-docs/v1/swagger.json", "My API V1");
})

Modify Swagger with Request Context(通过Request Context修改Swagger.)

如果你需要根据当前的请求设置一些Swagger的元数据,你可以配置一个在序列化文档之前执行的过滤器。

app.UseSwagger(c =>
{
    c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Host = httpReq.Host.Value);
});

SwaggerDocument 和当前的HttpRequest被传递到过滤器。这提供了很大的灵活性。例如,你可以分配“host”属性(如图所示),或者,你可以检查会话信息或授权标题,并根据用户权限删除该文档的操作。

Swashbuckle.AspNetCore.SwaggerGen

List Operation Responses (列表操作响应)###

...在默认情况下,Swashbuckle 将为每个操作生成“200”响应对于每个操作,如果该操作返回响应DTO,然后,它将被用于为响应体生成一个“模式”.例如:

[HttpPost("{id}")]
public Product GetById(int id)

将生成以下响应元数据:

responses: {
  200: {
    description: "Success",
    schema: {
      $ref: "#/definitions/Product"
    }
  }
}

Explicit Responses(明确的回答)

如果您需要指定不同的状态码 和/或 额外的响应。或者你的Action 返回 IActionResult而不是响应DTO.你可以用它来描述显式的反应ProducesResponseTypeAttribute附带ASP.NET Core 。例如:

[HttpPost("{id}")]
[ProducesResponseType(typeof(Product), 200)]
[ProducesResponseType(typeof(IDictionary), 400)]
[ProducesResponseType(typeof(void), 500)]
public IActionResult GetById(int id)

将生成以下响应元数据:

responses: {
  200: {
    description: "Success",
    schema: {
      $ref: "#/definitions/Product"
    }
  },
  400: {
    description: "Bad Request",
    schema: {
      type: "object",
      additionalProperties: {
        type: "string"
      }
    }
  },
  500: {
    description: "Server Error"
  }
}

Include Descriptions from XML Comments(包括来自XML注释的描述)

为了使用对人友好的描述来增强生成的文档,您可以对控制器和模型进行注释。Xml Comments 和配置Swashbuckle去将这些注释合并到输出Swagger JSON中。

  1. 为你的项目打开属性对话框,单击“Build”选项卡,并确保检查“XML 文件”这将生成一个包含在构建时包含所有XML注释的文件.

在这个点上,任何没有XML注释的类或方法都将触发构建警告,为了抑制这一点,在属性对话框中输入警告代码“1591”进入“抑制警告”字段

  1. 配置Swashbuckle 将XML注释合并到生成的文件中到Swagger JSON文件中:
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1",
            new Info
            {
                Title = "My API - V1",
                Version = "v1"
            }
         );

         var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "MyApi.xml");
         c.IncludeXmlComments(filePath);
    }
  1. 使用摘要,注释和响应标记注释您的操作。
    /// 
    /// Retrieves a specific product by unique id
   /// 通过唯一id检索特定产品
    /// 
    /// Awesomeness!
    /// Product created
    /// Product has missing/invalid values
    /// Oops! Can't create your product right now
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Product), 200)]
    [ProducesResponseType(typeof(IDictionary), 400)]
    [ProducesResponseType(typeof(void), 500)]
    public Product GetById(int id)
  1. 重新构建您的项目,以更新XML注释文件。和导航到Swagger json.请注意这些描述是如何映射到相应的swagger领域的。

注意:你还可以通过注释API模型及其属性来提供swagger的模式描述,如果你有多个XML注释文件(例如,用于控制器和模型的独立库),你可以多次调用include xml注释方法,它们都将被合并到输出的swagger JSON中。

Provide Global API Metadata(提供全球API元数据.)

除了Paths, Operations and Responses哪个Swashbuckle 为你生成,Swagger还支持全球元数据(see http://swagger.io/specification/#swaggerObject).。例如,你还可以为你的API提供完整的描述,服务条款,甚至是联系和许可信息。

c.SwaggerDoc("v1",
    new Info
    {
        Title = "My API - V1",
        Version = "v1",
        Description = "A sample API to demo Swashbuckle",
        TermsOfService = "Knock yourself out",
        Contact = new Contact
        {
            Name = "Joe Developer",
            Email = "[email protected]"
        },
        License = new License
        {
            Name = "Apache 2.0",
            Url = "http://www.apache.org/licenses/LICENSE-2.0.html"
        }
    }
)

使用IntelliSense来查看其他字段的可用性.

Generate Multiple Swagger Documents(生成多个Swagger文档)

通过上面描述的设置,生成器将包含所有的API操作,在一个Swagger的文档中.但是,如果需要,可以创建多个文档,例如,您可以需要为API的每个版本分别提供一个单独的文档,要做到这一点,首先要在创业公司中定义多个Swagger文件在Startup.cs

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info { Title = "My API - V1", Version = "v1" });
    c.SwaggerDoc("v2", new Info { Title = "My API - V2", Version = "v2" });
})

请注意第一个论点关于SwaggerDoc,它必须是一个url友好的名称,惟一地标识文档,它随后被用于提出请求相应的swgger json.例如,使用默认路由,上面的文档将可以在"/swagger/v1/swagger.json" 和 "/swagger/v2/swagger.json"

下一步,你需要通知swagger,在每个文档中包含哪些操作。尽管这可以定制(见下),但默认情况下,生成器将使用ApiDescription.GroupName 属性。与ASP.NET Core一起使用的内置元数据层,这种区别,您可以装饰单个操作或应用程序广泛的约定来设置。

Decorate Individual Actions(装修个人行为)

在一个特定的swagger 的文件中包含一个action,装饰它用ApiExplorerSettingsAttribute和设置GroupName相应的文档名称(区分大小写)

[HttpPost]
[ApiExplorerSettings(GroupName = "v2")]
public void Post([FromBody]Product product)

Assign Actions to Documents by Convention(按照约定对文档进行操作)

按惯例分组而不是装饰每一个action,你可以使用自定义控制器或action 约定,例如,您可以连接以下约定,根据控制器名称空间为文档分配操作。

// ApiExplorerGroupPerVersionConvention.cs
public class ApiExplorerGroupPerVersionConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        var controllerNamespace = controller.ControllerType.Namespace; // e.g. "Controllers.V1"
        var apiVersion = controllerNamespace.Split('.').Last().ToLower();

        controller.ApiExplorer.GroupName = apiVersion;
    }
}

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(c =>
        c.Conventions.Add(new ApiExplorerGroupPerVersionConvention())
    );
    
    ...
}

Customize the Action Selection Process(定制Action选择过程)

当为某个swagge的文件选择Action时,生成器调用一个DocInclusionPredicate来反对由框架所浮现的每个ApiDescription。默认的实现检查 ApiDescription.GroupName ,如果值为null或等于请求的文档名,则返回true.但是,你也可以提供一个自定义的inclusion predicate.。例如,如果你使用基于属性的方法来实现API版本控制。(eg:Microsoft.AspNetCore.Mvc.Versioning)你可以配置一个自定义的predicate,利用这个的手段。

c.DocInclusionPredicate((docName, apiDesc) =>
{
    var versions = apiDesc.ControllerAttributes()
        .OfType()
        .SelectMany(attr => attr.Versions);

    return versions.Any(v => $"v{v.ToString()}" == docName);
});

Exposing Multiple Documents through the UI (通过UI公开多个文档.)####

如果您使用的是 SwaggerUI 中间件,那么您需要指定您想要公开的任何其他的swagger端点,更多的信息,请参阅清单上的多分swagger的文档See List Multiple Swagger Documents for more.

Omit Obsolete Operations and/or Schema Properties(省略已经过时的的操作和/或模式属性)

The Swagger spec包含一个“弃用”标志,用于指示一个操作已被弃用,并且应该避免使用,如果相应的动作被废弃的ObsoleteAttribute.属性装饰,swagger的发生器将自动设置这个标志,但是,您可以配置生成器,而不是设置一个标志,而是完全忽略已经过时的操作。

services.AddSwaggerGen(c =>
{
    ...
    c.IgnoreObsoleteActions();
};

类似的方法也可以用于在swagger的输出中省略掉过时的属性。也就是说,您可以ObsoleteAttribute 使用来装饰模型属性,并配置Swashbuckle来生成JSON模式时忽略掉这些属性:

services.AddSwaggerGen(c =>
{
    ...
    c.IgnoreObsoleteProperties();
};

Omit Arbitrary Operations (省略任意操作)

你可以通过修饰个人行为来忽略那么swagger的输出.或者应用广泛的应用程序。

Decorate Individual Actions(装饰个人行为)

省略特定的动作,用它ApiExplorerSettingsAttribute来装饰,和设置IgnoreApi 标志。

[HttpGet("{id}")]
[ApiExplorerSettings(IgnoreApi = true)]
public Product GetById(int id)

Omit Actions by Convention(省略行为通过约定)

按照约定省略actions,而不是单独装饰它们。你可以应用一个自定义动作约定,例如,你可以将下面的约定连接到只记录Get操作。

// ApiExplorerGetsOnlyConvention.cs
public class ApiExplorerGetsOnlyConvention : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        action.ApiExplorer.IsVisible = action.Attributes.OfType().Any();
    }
}

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(c =>
        c.Conventions.Add(new ApiExplorerGetsOnlyConvention())
    );
    
    ...
}

Customize Operation Tags (e.g. for UI Grouping) (自定义操作标签(例如:UI 分组))###

The Swagger spec允许你有一个或者多个tags"被分配到每一个操作。swagger生成器将使用控制器名称作为默认的tag.如果你用得是SwaggerUI 中间件当它使用这个值来操作时.

You can override the default tag by providing a function that applies tags by convention. For example, the following configuration will tag, and therefore group operations in the UI, by HTTP method:您可以通过提供按约定应用标志的函数来覆盖缺省标志。例如,下面的配置将标签,所以,分组操作在UI,通过HTTP 方法。

services.AddSwaggerGen(c =>
{
    ...
    c.TagActionsBy(api => api.HttpMethod);
};

Change Operation Sort Order (e.g. for UI Sorting)更改操作排序顺序(eg,用于UI排序。)

默认情况下,操作是由指定的标记(见上图)排序的,然后徐它们被分组到基于路径的,层次结构这是由Swagger spec.你可以使用自定义排序策略来更改此行为。

services.AddSwaggerGen(c =>
{
    ...
    c.OrderActionsBy((apiDesc) => $"{apiDesc.ControllerName()}_{apiDesc.HttpMethod}");
};

注意:这就要求在将操作分组并转换成swagger的格式之间进行排序,因此,它们会影响群体的排序(也就是 Swagger PathItems),以及在一个分组的操作下,输出在swagger中。

Customize Schema Id's(定制模式Id)

如果生成器遇到复杂的参数或响应类型,它将生成相应的json模型,将其添加到全局定义中,并通过唯一id引用操作描述。例如,如果你有一个返回“Product”类型的操作,生成的模式将被引用如下:

responses: {
  200: {
    description: "Success",
    schema: {
      $ref: "#/definitions/Product"
    }
  }
} 

然而,如果它在不同的命名空间下遇到多个"Product"类(e.g. "RequestModels.Product" & "ResponseModels.Product"),Swashbuckle 将会引发一个异常“Conflicting schemaIds”,在这种情况下,你需要提供一个定制的id策略来进一步限定名称。

services.AddSwaggerGen(c =>
{
    ...
    c.CustomSchemaIds((type) => type.FullName);
};

Customize Schema for Enum Types(用于枚举类型的自定义模式)

在描述参数和响应时,Swashbuckle会尽力反映应用程序的序列化设置,例如, 如果启用了 CamelCaseContractResolver ,模式属性名称将在生成的swagger中出现以camelCased 。

类似于enum类型,如果启用了StringEnumConverter,那么相应的模式将列出枚举的名称,而不是整数值。

对于大多数情况,这就足够了,但是,如果需要更多的控制,Swashbuckle公开以下选项以覆盖默认行为。

services.AddSwaggerGen(c =>
{
    ...
    c.DescribeAllEnumsAsStrings();
    c.DescribeStringEnumsInCamelCase();
};

Override Schema for Specific Types(针对特定类型的覆盖模式)

开箱即用,Swashbuckle 在生成json模式时做了一份体面的工作,准确地描述了你的请求和响应。但是,如果你正在为API中的某些类型定制序列化行为,您可能需要帮助它。

例如,你可能有一个具有多个属性的类,你希望在json中表示为一个逗号分隔的字符串。要做到这一点,你可能需要实现一个定制的json转换器JsonConverter,在这种情况下,Swashbuckle不知道转换器是如何实现的,所以您需要为他提供一个准确描述类型的模式:

// PhoneNumber.cs
public class PhoneNumber
{
    public string CountryCode { get; set; }

    public string AreaCode { get; set; }

    public string SubscriberId { get; set; }
}

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    c.MapType(() => new Schema { Type = "string" });
};

Extend Generator with Operation, Schema & Document Filters (使用操作,模式和文档过滤器扩展生成器。)###

Swashbuckle 公开一个与生成过程挂钩的过滤器管道,一旦生成,单独的元数据对象就被传递到管道中,可以进一步修改它们。您可以为操作连接一个或多个自定义过滤器,for Operation, Schema and Document objects: Swashbuckle

Operation Filters(操作过滤器)

Swashbuckle 恢复一个ApiDescription,ASP.NET Core的一部分,对于每一个action和使用它去生成一个大的Swagger Operation一旦生成,它通过配置的过滤器列表操作OperationApiDescription

在一个典型的筛选器中,你检查ApiDescription的相关信息(eg:route info, action attributes etc.)和相应地更新 swagger Operation,例如,下面的过滤器列出了一个额外的“401”响应,用于处理所有被装饰_AuthorizeAttribute的动作。

// AuthResponsesOperationFilter.cs
public class AuthResponsesOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        var authAttributes = context.ApiDescription
            .ControllerAttributes()
            .Union(context.ApiDescription.ActionAttributes())
            .OfType();

        if (authAttributes.Any())
            operation.Responses.Add("401", new Response { Description = "Unauthorized" });
    }
}

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    c.OperationFilter();
};

NOTE: Filter pipelines are DI-aware. That is, you can create filters with constructor parameters and if the parameter types are registered with the DI framework, they'll be automatically injected when the filters are instantiated

Schema Filters

Swashbuckle generates a Swagger-flavored JSONSchema for every parameter, response and property type that's exposed by your controller actions. Once generated, it passes the Schema and Type through the list of configured Schema Filters.

The example below adds an AutoRest vendor extension (see https://github.com/Azure/autorest/blob/master/docs/extensions/readme.md#x-ms-enum) to inform the AutoRest tool how enums should be modelled when it generates the API client.

// AutoRestSchemaFilter.cs
public class AutoRestSchemaFilter : ISchemaFilter
{
    public void Apply(Schema schema, SchemaFilterContext context)
    {
        var typeInfo = context.SystemType.GetTypeInfo();

        if (typeInfo.IsEnum)
        {
            schema.Extensions.Add(
                "x-ms-enum",
                new { name = typeInfo.Name,  modelAsString = true }
            );
        };
    }
}

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    c.SchemaFilter();
};

Document Filters

Once a Swagger Document has been generated, it too can be passed through a set of pre-configured Document Filters. This gives full control to modify the document however you see fit. To ensure you're still returning valid Swagger JSON, you should have a read through the specification before using this filter type.

The example below provides a description for any tags that are assigned to operations in the document:

public class TagDescriptionsDocumentFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        swaggerDoc.Tags = new[] {
            new Tag { Name = "Products", Description = "Browse/manage the product catalog" },
            new Tag { Name = "Orders", Description = "Submit orders" }
        };
    }
}

NOTE: If you're using the SwaggerUI middleware, this filter can be used to display additional descriptions beside each group of Operations.

Add Security Definitions and Requirements

In Swagger, you can describe how your API is secured by defining one or more Security Scheme's (e.g basic, api key, oauth etc.) and declaring which of those schemes are applicable globally OR for specific operations. For more details, take a look at the "securityDefinitions" and "security" fields in the Swagger spec.

You can use some of the options described above to include security metadata in the generated Swagger Document. The example below adds an OAuth 2.0 definition to the global metadata and a corresponding Operation Filter that uses the presence of an AuthorizeAttribute to determine which operations the scheme applies to.

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    // Define the OAuth2.0 scheme that's in use (i.e. Implicit Flow)
    c.AddSecurityDefinition("oauth2", new OAuth2Scheme
    {
        Type = "oauth2",
        Flow = "implicit",
        AuthorizationUrl = "http://petstore.swagger.io/oauth/dialog",
        Scopes = new Dictionary
        {
            { "readAccess", "Access read operations" },
            { "writeAccess", "Access write operations" }
        }
    });
    // Assign scope requirements to operations based on AuthorizeAttribute
    c.OperationFilter();
};

// SecurityRequirementsOperationFilter.cs
public class SecurityRequirementsOperationFilter : IOperationFilter
{
    private readonly IOptions authorizationOptions;

    public SecurityRequirementsOperationFilter(IOptions authorizationOptions)
    {
        this.authorizationOptions = authorizationOptions;
    }

    public void Apply(Operation operation, OperationFilterContext context)
    {
        var controllerPolicies = context.ApiDescription.ControllerAttributes()
            .OfType()
            .Select(attr => attr.Policy);
        var actionPolicies = context.ApiDescription.ActionAttributes()
            .OfType()
            .Select(attr => attr.Policy);
        var policies = controllerPolicies.Union(actionPolicies).Distinct();
        var requiredClaimTypes = policies
            .Select(x => this.authorizationOptions.Value.GetPolicy(x))
            .SelectMany(x => x.Requirements)
            .OfType()
            .Select(x => x.ClaimType);

        if (requiredClaimTypes.Any())
        {
            operation.Responses.Add("401", new Response { Description = "Unauthorized" });
            operation.Responses.Add("403", new Response { Description = "Forbidden" });

            operation.Security = new List>>();
            operation.Security.Add(
                new Dictionary>
                {
                    { "oauth2", requiredClaimTypes }
                });
        }
    }
}

NOTE: If you're using the SwaggerUI middleware, you can enable interactive OAuth2.0 flows that are powered by the emitted security metadata. See Enabling OAuth2.0 Flows for more details.

Swashbuckle.AspNetCore.SwaggerUI

Change Relative Path to the UI

By default, the Swagger UI will be exposed at "/swagger". If necessary, you can alter this when enabling the SwaggerUI middleware:

app.UseSwaggerUI(c =>
{
    c.RoutePrefix = "api-docs"
    ...
}

Change Document Title

By default, the Swagger UI will have a generic document title. When you have multiple Swagger pages open, it can be difficult to tell them apart. You can alter this when enabling the SwaggerUi middleware:

app.UseSwaggerUi(c =>
{
    c.DocumentTitle("My Swagger UI");
    ...
}

List Multiple Swagger Documents

When enabling the middleware, you're required to specify one or more Swagger endpoints (fully qualified or relative to the current host) to power the UI. If you provide multiple endpoints, they'll be listed in the top right corner of the page, allowing users to toggle between the different documents. For example, the following configuration could be used to document different versions of an API.

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
    c.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 Docs");
}

Apply swagger-ui Parameters

The swagger-ui ships with it's own set of configuration parameters, all described here https://github.com/swagger-api/swagger-ui#swaggerui. In Swashbuckle, most of these are surfaced through the SwaggerUI middleware options:

app.UseSwaggerUI(c =>
{
    c.EnabledValidator();
    c.BooleanValues(new object[] { 0, 1 });
    c.DocExpansion("full");
    c.InjectOnCompleteJavaScript("/swagger-ui/on-complete.js");
    c.InjectOnFailureJavaScript("/swagger-ui/on-failure.js");
    c.SupportedSubmitMethods(new[] { "get", "post", "put", "patch" });
    c.ShowRequestHeaders();
    c.ShowJsonEditor();
});

Most of them are self explanatory, mapping back to the corresponding swagger-ui docs. To inject custom JavaScript (i.e. InjectOnCompleteJavaScript and InjectOnFailureJavaScript), you'll need to add the scripts to your application and provide the relative paths as shown above. In ASP.NET Core, this is easily done by placing your script files in the wwwroot folder.

Inject Custom CSS

To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your wwwroot folder and specifying the relative paths in the middleware options:

app.UseSwaggerUI(c =>
{
    ...
    c.InjectStylesheet("/swagger-ui/custom.css");
}

Enable OAuth2.0 Flows

The swagger-ui has built-in support to participate in OAuth2.0 authorization flows. It interacts with authorization and/or token endpoints, as specified in the Swagger JSON, to obtain access tokens for subsequent API calls. See Adding Security Definitions and Requirements for an example of adding OAuth2.0 metadata to the generated Swagger.

If you're Swagger endpoint includes the appropriate security metadata, you can enable the UI interaction as follows:

app.UseSwaggerUI(c =>
{
    ...
    // Provide client ID, client secret, realm and application name
    c.ConfigureOAuth2("swagger-ui", "swagger-ui-secret", "swagger-ui-realm", "Swagger UI");
}

你可能感兴趣的:(domaindrivendev/Swashbuckle.AspNetCore)