Aviso importante se você estiver atualizando entre as principais versões! |
---|
* Se você estiver atualizando de 4.x para 5.x, há várias mudanças de ruptura a serem cientes. Veja as notas de lançamento para obter detalhes * Se você está saltando de 3.x para 4.x primeiro, também haverá dragões. Veja aquelas notas de lançamento aqui |
Ferramentas de swagger para APIs criadas com asp.net Core. Gere uma bela documentação da API, incluindo uma interface do usuário para explorar e testar operações, diretamente de suas rotas, controladores e modelos.
Além do gerador Swagger 2.0 e OpenAPI 3.0, o Swashbuckle também fornece uma versão incorporada do incrível Swagger-Ui que é alimentado pelo Swagger JSON gerado. Isso significa que você pode complementar sua API com documentação viva que está sempre em sincronia com o código mais recente. O melhor de tudo é que requer codificação e manutenção mínimas, permitindo que você se concentre na criação de uma API incrível.
E isso não é tudo ...
Depois de ter uma API que possa se descrever em Swagger, você abriu o baú de ferramentas baseadas em arrogância, incluindo um gerador de clientes que pode ser direcionado para uma ampla gama de plataformas populares. Veja Swagger-Codegen para obter mais detalhes.
Versão do Swashbuckle | ASP.NET CORE | Swagger / Openapi Spec. | Swagger-ui | Redoc UI |
---|---|---|---|---|
CI | > = 2.0.0 | 2.0, 3.0 | 5.xx | 2.xx |
6.9.0 | > = 2.0.0 | 2.0, 3.0 | 5.17.14 | 2.1.5 |
5.6.3 | > = 2.0.0 | 2.0, 3.0 | 3.32.5 | 2.0.0-rc.40 |
4.0.0 | > = 2.0.0, <3.0.0 | 2.0 | 3.19.5 | 1.22.2 |
3.0.0 | > = 1.0.4, <3.0.0 | 2.0 | 3.17.1 | 1.20.0 |
2.5.0 | > = 1.0.4, <3.0.0 | 2.0 | 3.16.0 | 1.20.0 |
Instale o pacote NUGET padrão no seu aplicativo ASP.NET CORE.
Package Manager : Install-Package Swashbuckle.AspNetCore CLI : dotnet add package Swashbuckle.AspNetCore
No método ConfigureServices
do Startup.cs
, registre o gerador de swagger, definindo um ou mais documentos de arrogância.
usando o Microsoft.openapi.models;
serviços.addmvc (); serviços.addswaggergen (c => {c.swaggerdoc ("v1", novo openApiinfo {title = "my Api", versão = "v1"});});
Certifique -se de que suas ações e parâmetros da API sejam decorados com "http" e "de" explícitos explícitos.
[HTTPPOST] Public void createproduct (produto [Frombody] Produto) ...
[Httpget] public ienumerable <Product> SearchProducts ([FORMQUERY] String Palavras -chave) ...
Nota: Se você omitir as ligações explícitas de parâmetros, o gerador as descreverá como parâmetros de "consulta" por padrão.
No método Configure
, você deve expor a arrogância gerada como JSON endpoint (s) por um dos seguintes métodos:
App.MapendPoints (endpoints => {// ... endpoints.mapswagger ();});
App.USesWagger ();
Neste ponto, você pode aumentar seu aplicativo e visualizar o Swagger JSON gerado em "/swagger/v1/swagger.json".
Insira o middleware
Adicione pontos de extremidade se você estiver usando o roteamento baseado em terminais.
Opcionalmente, insira o middleware Swagger-UI se desejar expor a documentação interativa, especificando o (s) endpoint (s) Swagger JSON para alimentá-lo.
App.Useswaggerui (c => {c.swageGerendPoint ("v1/swagger.json", "meu api v1");});
Agora você pode reiniciar seu aplicativo e conferir os documentos interativos gerados automaticamente em "/swagger".
Nas versões anteriores a 5.0.0
, o Swashbuckle gerará esquemas (descrições dos tipos de dados expostos por uma API) com base no comportamento do serializador de Newtonsoft . Isso fazia sentido, porque esse era o serializador que enviou com o ASP.NET Core na época. No entanto, desde a versão 3.0.0
, o ASP.NET Core apresenta um novo Systemer System.Text.json (STJ) pronto para uso e, se você deseja continuar usando o Newtonsoft , precisa instalar um pacote separado e explicitamente Opta-in. Do swashbuckle 5.0.0
e além de um padrão semelhante é usado. Ou seja, o Swashbuckle pronta para uso assumirá que você está usando o serializador do STJ e gerará esquemas com base em seu comportamento. Se você estiver usando o Newtonsoft , precisará instalar um pacote de swashbuckle separado e optar explicitamente. Esta é uma etapa necessária, independentemente de qual versão do ASP.NET CORE você está usando .
Resumindo ...
Se você estiver usando o System.Text.json (STJ) , a configuração descrita acima será suficiente e as opções/atributos STJ serão automaticamente homenageadas pelo gerador Swagger.
Se você estiver usando o Newtonsoft , precisará instalar um pacote separado e optar explicitamente para garantir que as configurações/atributos do Newtonsoft sejam automaticamente homenageados pelo gerador de swagger:
Package Manager : Install-Package Swashbuckle.AspNetCore.Newtonsoft CLI : dotnet add package Swashbuckle.AspNetCore.Newtonsoft
serviços.addmvc (); serviços.addswaggergen (c => {c.swaggerdoc ("v1", new OpenApiinfo {title = "my API", versão = "v1"});}); Services.addswaggergennewtonsoftsupport (); // Opt -in explícito - precisa ser colocado após Addswaggergen ()
O swashbuckle depende muito do ApiExplorer
, a camada de metadados da API que é enviada com o núcleo do ASP.NET. Se você estiver usando o ajudante AddMvc
para inicializar a pilha MVC, o APIEXPlorer será registrado automaticamente e o SB funcionará sem problemas. No entanto, se você estiver usando AddMvcCore
para uma pilha MVC mais emparelhada, precisará adicionar explicitamente o serviço APIEXPLORER:
Services.addmvccore (). AddaPiexPlorer ();
Além disso, se você estiver usando o roteamento convencional (em vez de atribuir o roteamento), quaisquer controladores e as ações nos controladores que usam roteamento convencional não serão representados no apiexplorer, o que significa que o Swashbuckle não será capaz de encontrar esses controladores e gerar arrogância operações deles. Por exemplo:
App.UseMVC (rotas => {// Swaggergen não encontrará controladores que sejam roteados através desta técnica. Rotes.Maproute ("padrão", "{controller = home}/{Action = index}/{id?}") ;});
Você deve usar o roteamento de atributos para qualquer controlador que desejar representado em seu (s) documento (s) Swagger:
[Rota ("exemplo")] classe pública ExampleController: Controller {[httpget ("")] public iactionResult Dostuff () { / ** /}}
Consulte a documentação de roteamento para obter mais informações.
O Swashbuckle consiste em vários componentes que podem ser usados juntos ou individualmente, dependendo de suas necessidades. Na sua essência, há um gerador de arrogância, middleware para expô-lo como pontos de extremidade JSON e uma versão embalada do Swagger-Ui. Esses três pacotes podem ser instalados com o Swashbuckle.AspNetCore
"Metapackage" e trabalharão juntos sem problemas (consulte o início) para fornecer belos documentos de API que são gerados automaticamente a partir do seu código.
Além disso, existem pacotes complementares (ferramentas da CLI, uma interface do usuário alternativa etc.) que você pode instalar e configurar opcionalmente conforme necessário.
Pacote | Descrição |
---|---|
Swashbuckle.aspnetcore.swagger | Expõe pontos de extremidade Swagger JSON. Ele espera que uma implementação do ISwaggerProvider seja registrada no contêiner DI, que ele consulta para recuperar OpenAPIDocument(s) que são então expostos como JSON serializado |
Swashbuckle.aspnetcore.swaggergen | Injeta uma implementação do ISwaggerProvider que pode ser usado pelo componente acima. Esta implementação específica gera OpenApiDocument(s) de suas rotas, controladores e modelos |
Swashbuckle.aspnetcore.swaggerui | Expõe uma versão incorporada do Swagger-Ui. Você especifica os pontos de extremidade da API onde podem obter Swagger JSON, e ele os usa para alimentar documentos interativos para sua API |
Pacote | Descrição |
---|---|
Swashbuckle.aspnetcore.annotações | Inclui um conjunto de atributos personalizados que podem ser aplicados a controladores, ações e modelos para enriquecer a arrogância gerada |
Swashbuckle.aspnetcore.cli | Fornece uma interface da linha de comando para recuperar o Swagger diretamente de uma montagem de inicialização e a gravação do arquivo |
Swashbuckle.aspnetcore.redoc | Expõe uma versão incorporada da interface do usuário Redoc (uma alternativa ao Swagger-Ui) |
Esses pacotes são fornecidos pela comunidade de código aberto.
Pacote | Descrição |
---|---|
Swashbuckle.aspnetcore.filters | Alguns filtros úteis de swashbuckle que adicionam documentação adicional, por exemplo, exemplos de solicitação e resposta, informações de autorização, etc. Consulte seu ReadMe para obter mais detalhes |
Unchase.swashbuckle.aspnetcore.extensions | Algumas extensões úteis (filtros), que adicionam documentação adicional, por exemplo, oculam pathitems para funções inaceitadas, fixam enum para a geração de código do cliente, etc. Consulte seu ReadMe para obter mais detalhes |
Microelements.swashbuckle.fluentValidation | Use regras de fluentValidação em vez de atributos do componente Model para aumentar os esquemas de swagger gerados gerados |
Mmlib.swaggerforocelot | Documentações agregadas sobre microsserviços diretamente no Ocelot API Gateway |
As etapas descritas acima o levarão a funcionar com a configuração mínima. No entanto, o Swashbuckle oferece muita flexibilidade para personalizar como você achar melhor. Confira a tabela abaixo para obter a lista completa de opções:
Swashbuckle.aspnetcore.swagger
Mude o caminho para os pontos finais do Swagger JSON
Modifique o Swagger com o contexto de solicitação
Serialize Swagger JSON no formato 2.0
Trabalhando com diretórios virtuais e proxies reversos
Personalizando como o documento OpenAPI é serializado
Swashbuckle.aspnetcore.swaggergen
Atribuir operações explícitas
Listar respostas de operações
Bandeira exigida parâmetros e propriedades de esquema
Manipular formulários e uploads de arquivo
Lidar com downloads de arquivos
Inclua descrições de comentários XML
Fornecer metadados da API global
Gerar vários documentos de arrogância
Omita operações obsoletas e/ou propriedades de esquema
Omita operações arbitrárias
Personalize tags de operação (por exemplo, para agrupamento da interface do usuário)
Altere a ordem de classificação da operação (por exemplo, para a classificação da interface do usuário)
Personalize o Schema IDs
Substituir esquema para tipos específicos
Estender o gerador com operação, esquema e filtros de documentos
Adicionar definições e requisitos de segurança
Adicione definições e requisitos de segurança para a autenticação do portador
Herança e polimorfismo
Swashbuckle.aspnetcore.swaggerui
Mude o caminho relativo para a interface do usuário
Alterar o título do documento
Alterar caminhos CSS ou JS
Liste vários documentos de arrogância
Aplique parâmetros Swagger-UI
Injetar javascript personalizado
Injetar CSS personalizado
Personalize Index.html
Ativar fluxos OAuth2.0
Use solicitação do lado do cliente e interceptores de resposta
Swashbuckle.aspnetcore.annotações
Instale e habilite anotações
Enriqueça os metadados da operação
Enriqueça metadados de resposta
Enriqueça os metadados dos parâmetros
Enriqueça os metadados do pedido de solicitação
Enriqueça os metadados do esquema
Aplique filtros de esquema a tipos específicos
Adicione os metadados da tag
Swashbuckle.aspnetcore.cli
Recuperar Swagger diretamente de uma montagem de inicialização
Use a ferramenta CLI com uma configuração de host personalizada
Swashbuckle.aspnetcore.redoc
Mude o caminho relativo para a interface do usuário
Alterar o título do documento
Aplique parâmetros Redoc
Injetar CSS personalizado
Personalize Index.html
Por padrão, Swagger JSON será exposto na rota a seguir - "/swagger/{documentName }/swagger.json". Se necessário, você pode alterar isso ao ativar o middleware de arrogância. As rotas personalizadas devem incluir o parâmetro {documentName}
.
app.useswagger (c => {c.RouteTemplate = "API-DOCS/{DocumentName} /swagger.json";})
Nota: Se você estiver usando o middleware swaggerui, também precisará atualizar sua configuração para refletir os novos pontos de extremidade:
App.Useswaggerui (c => {c.swagegerendpoint ("/api-docs/v1/swagger.json", "meu api v1");})
Nota: Se você também precisar atualizar o caminho relativo em que a própria interface do usuário está disponível, precisará seguir as instruções encontradas no caminho relativo da mudança para a interface do usuário.
Se você precisar definir alguns metadados do Swagger com base na solicitação atual, poderá configurar um filtro executado antes da serialização do documento.
App.USesWagger (C => {C.PreserializeFilters.Add ((Swagger, httpreq) => {swagger.servers = new List <CopenApiserver> {new OpenApiserver {url = $ "{httpreq.scheme}: // {httpreq. Host.value} "}};});});
O OpenApiDocument
e o HttpRequest
atual são passados para o filtro. Isso fornece muita flexibilidade. Por exemplo, você pode adicionar um servidor de API explícito com base no cabeçalho do "host" (como mostrado), ou pode inspecionar as informações da sessão ou um cabeçalho de autorização e remover operações do documento com base nas permissões do usuário.
Por padrão, o Swashbuckle gerará e exporá o Swagger JSON na versão 3.0 da especificação, oficialmente chamado de especificação OpenAPI. No entanto, para apoiar a compatibilidade com versões anteriores, você pode optar por continuar expondo -o no formato 2.0 com a seguinte opção:
App.Useswagger (C => {C.Serializeasv2 = true;});
Diretórios virtuais e proxies reversos podem causar problemas para aplicativos que geram links e redirecionamentos, principalmente se o aplicativo retornar URLs absolutos com base no cabeçalho Host
e em outras informações da solicitação atual. Para evitar esses problemas, o Swashbuckle usa URLs relativos sempre que possível e incentiva seu uso ao configurar o middleware Swaggerui e Redoc.
Por exemplo, para conectar o middleware Swaggerui, você fornece o URL a um ou mais documentos do OpenAPI/Swagger. Este é o URL que o Swagger-UI, um aplicativo do lado do cliente, ligará para recuperar seus metadados da API. Para garantir que isso funcione por trás de diretórios virtuais e proxies reversos, você deve expressar isso em relação ao RoutePrefix
do próprio Swagger-Ui:
App.Useswaggerui (c => {c.RoutePrefix = "swagger"; c.swageRendPoint ("v1/swagger.json", "meu api v1");});
NOTA: Nas versões anteriores dos documentos, você pode ter visto isso expresso como um link de raiz (por exemplo, /swagger/v1/swagger.json
). Isso não funcionará se o seu aplicativo estiver hospedado em um diretório virtual do IIS ou por trás de um proxy que aparar o caminho da solicitação antes de encaminhar. Se você mudar para a sintaxe da página-relativa mostrada acima, ela deve funcionar em todos os casos.
Por padrão, o Swashbuckle serializará o documento OpenAPI usando os métodos Serialize no objeto Document OpenAPI. Se uma serialização personalizada for desejada, é possível criar um serializador de documento personalizado que implemente a interface ISwaggerDocumentSerializer
. Isso pode ser definido nas SwaggerOptions
na coleção de serviços usando ConfigureSwagger()
:
Observação
Se você planeja usar a ferramenta de linha de comando para gerar arquivos de especificação do OpenAPI, isso deve ser feito na coleção de serviços usando ConfigureSwagger()
.
Services.ConfiguresWagger (Options => {Option.SetCustomDocumentSerializer <CustomDocumentSerializer> ();})
Quando a ferramenta de linha de comando não é usada, ela também pode ser feita no host do aplicativo:
app.useswagger (options => {options.setCustomDocumentSerializer <CustomDocumentSerializer> ();})
Em Swagger, as operações podem receber um operationId
. Esse ID deve ser único entre todas as operações descritas na API. Ferramentas e bibliotecas (por exemplo, geradores de clientes) podem usar o OperationId para identificar exclusivamente uma operação; portanto, é recomendável seguir convenções comuns de nomeação de programação.
A gerência automática de um ID que atenda a esses requisitos, além de fornecer um nome que seria significativo nas bibliotecas de clientes é uma tarefa não trivial e, portanto, o Swashbuckle omite o operationId
por padrão. No entanto, se necessário, você pode atribuir operationIds
decorando rotas individuais ou fornecendo uma estratégia personalizada.
Opção 1) Decorar rotas com uma propriedade Name
[Httpget ("{id}", name = "getProductById")] public iactionResult get (int id) // operaçãoId = "getProductById"
Opção 2) Forneça uma estratégia personalizada
// startup.csservices.addswaggergen (c => {... // use o nome do método como operação C.customoperationIds (apidesc => {return apidesc.trygetmethodinfo (out métodinfo methodinfo)? Metodinfo.name: null;});} ) // ProductScontroller.cs [httpget ("{id}")] public iaCtionResult getProductById (int id) // OperationId = "getProductById"
NOTA: Com qualquer uma das abordagens, os autores da API são responsáveis por garantir a singularidade de operationIds
em todas as operações
Por padrão, o Swashbuckle gerará uma resposta "200" para cada operação. Se a ação retornar uma resposta DTO, isso será usado para gerar um esquema para o corpo de resposta. Por exemplo ...
[Httppost ("{id}")] produto público getById (int id)
Produzirá os seguintes metadados de resposta:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
Se você precisar especificar um código de status diferente e/ou respostas adicionais, ou suas ações retornam IActionResult
em vez de um DTO de resposta, poderá descrever explicitamente as respostas com o ProducesResponseTypeAttribute
que é enviado com o ASP.NET Core. Por exemplo ...
[Httppost ("{id}")] [ProduceSResponseType (typeOf (Product), 200)] [ProduceSESPONSETYPE (TypeOf (Idictionary <String, String>), 400)] [ProduceSroSponseType (500)]
Produzirá os seguintes metadados de resposta:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } }, 400: { description: "Bad Request", content: { "application/json": { schema: { type: "object", additionalProperties: { type: "string" } } } } }, 500: { description: "Internal Server Error", content: {} } }
Em um documento Swagger, você pode sinalizar parâmetros e propriedades de esquema necessárias para uma solicitação. Se um parâmetro (de nível superior ou baseado em propriedade) for decorado com o BindRequiredAttribute
ou RequiredAttribute
, o Swashbuckle o sinalizará automaticamente como um parâmetro "necessário" na arrogância gerada:
// ProductScontroller.cspublic IACTIONRESULT Pesquisa ([FORMQUERY, BINDREQUEND] String Palavras -chave, [DO FORMO] PAGINGPARAMS PAGINGPARAMS) {if (! Modelstate.isValid) retorna BadRequest (ModelState);} // SearchParams.cspublic PaggageMs (ModelState); ] public int pageno {get; definir; } public int PageSize {get; definir; }}
Além dos parâmetros, o Swashbuckle também homenageará o RequiredAttribute
quando usado em um modelo que está vinculado ao órgão de solicitação. Nesse caso, as propriedades decoradas serão sinalizadas como propriedades "necessárias" na descrição do corpo:
// ProductScontroller.cspublic iaCtionResult Create ([Frombody] Produto) {if (! ModelState.isValid) retorna BadRequest (ModelState); ...} // Product.Cspublic Class Product {[Requerir] Public Name {get; definir; } public string description {get; definir; }}
Este controlador aceitará dois valores de campo de formulário e um upload de arquivo nomeado do mesmo formulário:
[Httppost] public void uploadfile ([FROFFORM] String Descrição, [FromForm] DateTime ClientDate, arquivo iformFile)
NOTA IMPORTANTE: De acordo com os documentos principais do ASP.NET, você não deve decorar parâmetros
IFormFile
com o atributo[FromForm]
, pois a fonte de ligação é automaticamente inferida do tipo. De fato, o valor inferido éBindingSource.FormFile
e, se você aplicar o atributo, ele será definido comoBindingSource.Form
, que estragaApiExplorer
, o componente metadata que é enviado com o núcleo do ASP.NET e é fortemente invocado pelo swashbuckle. Uma questão específica aqui é que o Swaggerui não tratará o parâmetro como um arquivo e, portanto, não exibirá um botão de upload de arquivo, se você incluir erroneamente esse atributo.
ApiExplorer
(o componente de metadados do núcleo do asp.net que o Swashbuckle é construído) não aparece os tipos FileResult
por padrão e, portanto, você precisa dizer explicitamente com o atributo ProducesResponseType
(ou Produces
no .NET 5 ou mais):
[Httpget ("{filename}")] [ProducesResponseType (typeof (filestreamResult), statuscodes.status200ok, "image/jpeg")] public filestreamResult getFile (string filename)
Para aprimorar os documentos gerados com descrições amigáveis ao ser humano, você pode anotar ações e modelos do controlador com comentários XML e configurar o Swashbuckle para incorporar esses comentários ao Swagger JSON de saída:
Abra a caixa de diálogo Propriedades para o seu projeto, clique na guia "Construir" e verifique se "arquivo de documentação XML" está marcado ou adicione <GenerateDocumentationFile>true</GenerateDocumentationFile>
elemento à seção <PropertyGroup>
do seu arquivo de projeto .csproj. Isso produzirá um arquivo contendo todos os comentários XML no tempo de construção.
Neste ponto, quaisquer classes ou métodos que não sejam anotados com comentários XML desencadearão um aviso de construção. Para suprimir isso, digite o código de aviso "1591" no campo "suprimir os avisos" na caixa de diálogo Propriedades ou adicione <NoWarn>1591</NoWarn>
à seção <PropertyGroup>
do seu arquivo .csproj Project.
Configure o Swashbuckle para incorporar os comentários XML em arquivo no Swagger JSON gerado:
serviços.addswaggergen (c => {c.swaggerdoc ("v1", novo openApiinfo {title = "my API - v1", versão = "v1"}); c.includexmlComments (typeof (mycontroller) .assembly));}
Anote suas ações com resumo, observações, param e tags de resposta:
/// <summary> /// Recupera um produto específico por ID exclusivo /// </summary> /// <muils> Awesomeness! > O ID do produto </am Param> /// <Resposta Code = "200"> Produto Recuperado "500"> opa! Não posso procurar seu produto agora </swerwer> [httpget ("{id}")] [ProduStroSponseType (typeOf (Product), 200)] [ProduceSesponseType (404)] [ProdusestonseType (500)] Public Product GetById (int (int) eu ia)
Você também pode anotar tipos com tags de resumo e exemplo:
Public class Product {/// <summary> /// o nome do produto /// </summary> /// <semel> Sapatos de basquete masculino </somemlem> Nome da String public {get; definir; } /// <summary> /// Quantidade deixada em estoque /// </summary> /// <semel> 10 </exemplo> public int uknablestock {get; definir; } /// <summary> /// Os tamanhos que o produto está disponível em /// </summary> /// <Exemplo> ["Small", "Medium", "Large"] </somemlem> list <Lista < string> tamanhos {get; definir; }}
Reconstrua seu projeto para atualizar o arquivo de comentários XML e navegar até o ponto final do Swagger JSON. Observe como as descrições são mapeadas nos campos de arrogância correspondentes.
Nota: Você também pode fornecer descrições de esquema de swagger anotando seus modelos de API e suas propriedades com tags de resumo. Se você tiver vários arquivos de comentários XML (por exemplo, bibliotecas separadas para controladores e modelos), você poderá invocar o método de inclusãoxmlcomments várias vezes e todos serão mesclados no Swagger JSON de saída.
Além de "Pathitems", "Operações" e "Respostas", que o Swashbuckle gera para você, Swagger também suporta metadados globais (consulte https://swagger.io/specification/#oasobject). Por exemplo, você pode fornecer uma descrição completa para sua API, Termos de Serviço ou até informações de contato e licenciamento:
C.Swaggerdoc ("V1", novo OpenApiinfo {title = "My API - V1", Version = "V1", Descrição = "Uma API de amostra para Demo Swashbuckle", termosfservice = novo Uri ("http://tempuri.org /termos "), contato = new OpenApicontact {name =" Joe Developer ", email =" [email protected] "}, licença = new OpenApilicense {name =" Apache 2.0 ", url = novo Uri (" https: //www.apache.org/license/license-2.0.html ")}});
Dica: use o IntelliSense para ver quais outros campos estão disponíveis.
Com a configuração descrita acima, o gerador incluirá todas as operações da API em um único documento Swagger. No entanto, você pode criar vários documentos, se necessário. Por exemplo, você pode querer um documento separado para cada versão da sua API. Para fazer isso, comece definindo vários documentos de arrogância em Startup.cs
:
Serviços.addswaggergen (c => {c.swaggerdoc ("v1", novo openApiinfo {title = "my API - v1", versão = "v1"}); c.swaggerdoc ("v2", novo openapiinfo {title " Minha API - V2 ", versão =" V2 "});})
Tome nota do primeiro argumento para Swaggerdoc. Deve ser um nome amigável para Uri que identifique exclusivamente o documento. Posteriormente, é usado para compensar o caminho para solicitar o Swagger JSON correspondente. Por exemplo, com o roteamento padrão, os documentos acima estarão disponíveis em "/swagger/v1/swagger.json" e "/swagger/v2/swagger.json".
Em seguida, você precisará informar o Swashbuckle quais ações incluir em cada documento. Embora isso possa ser personalizado (veja abaixo), por padrão, o gerador usará a propriedade ApiDescription.GroupName
, parte da camada de metadados interna que é enviada com o núcleo do ASP.NET, para fazer essa distinção. Você pode definir isso decorando ações individuais ou aplicando uma convenção ampla de aplicativos.
Para incluir uma ação em um documento específico, decore -o com o ApiExplorerSettingsAttribute
e defina GroupName
para o nome do documento correspondente (Case Sensitive):
[Httppost] [apiexplorersettings (groupname = "v2")] public void post ([dobody] produto de produto)
Para agrupar por convenção em vez de decorar todas as ações, você pode aplicar um controlador ou convenção de ação personalizado. Por exemplo, você pode conectar a seguinte convenção para atribuir ações a documentos com base no espaço para nome do controlador.
// apiexplorerGroupperVersionConvention.Cspublic CLASS APIEXPLORERGROURPERVERSÃOCONVENÇÃO: icontrollemodelConVention {public void Aplicação (controlador controlador) {var controlNamespace = controlador.ControllerType.Namespace; // por exemplo, "Controllers.v1" var apiversion = controlNamespace.split ('.'). last (). tolower (); controller.apiexplorer.groupName = APIVERSION;}} // startup.cspublic void Configures (iservicecollection Services) { Services.addmvc (c => c.Conventions.add (novo apiexplorergroupperversionConvention ())); ...}
Ao selecionar ações para um determinado documento de swagger, o gerador chama um DocInclusionPredicate
contra cada ApiDescription
que é apresentado pela estrutura. A implementação padrão inspeciona ApiDescription.GroupName
e retorna true se o valor for nulo ou igual ao nome do documento solicitado. No entanto, você também pode fornecer um predicado de inclusão personalizado. Por exemplo, se você estiver usando uma abordagem baseada em atributos para implementar a versão da API (por exemplo, microsoft.aspnetcore.mvc.versioning), você pode configurar um predicado personalizado que aproveita os atributos de versão:
c.docinclusionPredicate ((DocName, ApidsC) => {if (! Apidesc.TtryGetMethodInfo (Out Metodinfo Methodinfo)) Retorno false; var versions = MethodInfo.DecLaringType .getCustomAtTributes (True) .Oftype <PiversOnTtRiFTRIBT) (). > attr.versions);
Se você estiver usando o middleware SwaggerUI
, precisará especificar quaisquer pontos de extremidade adicionais que desejarem expor. Consulte Lista Múltiplas documentos de Swagger para mais.
A especificação Swagger inclui um sinalizador deprecated
para indicar que uma operação está descontinuada e deve ser abstida do uso. O gerador de arrogância definirá automaticamente esse sinalizador se a ação correspondente for decorada com o ObsoleteAttribute
. No entanto, em vez de definir um sinalizador, você pode configurar o gerador para ignorar completamente as ações obsoletas:
Serviços.addswaggergen (c => {... c.ignoreObSoleteActions ();};
Uma abordagem semelhante também pode ser usada para omitir propriedades obsoletas dos esquemas na saída de arrogância. Ou seja, você pode decorar as propriedades do modelo com o ObsoleteAttribute
e configurar o Swashbuckle para omitir essas propriedades ao gerar esquemas JSON:
Serviços.addswaggergen (c => {... c.ignoreobSoleteProperties ();};
Você pode omitir operações da saída de arrogância decorando ações individuais ou aplicando uma convenção ampla de aplicativos.
Para omitir uma ação específica, decore -a com o ApiExplorerSettingsAttribute
e defina a bandeira IgnoreApi
:
[Httpget ("{id}")] [apiexplorersettings (ignoraeapi = true)] produto público getById (int id)
Para omitir ações por convenção em vez de decorá -las individualmente, você pode aplicar uma convenção de ação personalizada. Por exemplo, você pode conectar a seguinte convenção para documentar apenas as operações Get:
// APIEXPLORERGETSONLYCONVENTENT.CSPUBLIC APIEXPLORERGETSONLYCONVENTE: IACTIONMODelConvenção {public void Aplicação (ação de ação) {action.apiexplorer.isvisible = action.attributes.oftype <htttpTtTr> () OLCRECTION Serviços) {Services.addmvc (c => c.Conventions.add (novo apiexplorgetsonlyconvention ())); ...}
A especificação Swagger permite que uma ou mais "tags" sejam atribuídas a uma operação. O gerador de arrogância atribuirá o nome do controlador como a tag padrão. É importante observar se você estiver usando o middleware SwaggerUI
, pois ele usa esse valor para agrupar operações.
Você pode substituir a tag padrão, fornecendo uma função que aplica tags por convenção. Por exemplo, a configuração a seguir marcará e, portanto, operações de grupo na interface do usuário, pelo método HTTP:
serviços.addswaggergen (c => {... c.Tagactionsby (api => api.httpmethod);};
Por padrão, as ações são ordenadas pela tag atribuída (veja acima) antes de serem agrupadas na estrutura aninhada e centrada no caminho da especificação Swagger. Mas você pode alterar a ordem padrão de ações com uma estratégia de classificação personalizada:
serviços.addswaggergen (c => {... c.ordeationsby ((apidesc) => $ "{apidesc.actionDescriptor.RoutEvalues [" controlador "]} _ {apidesc.httpmethod}");};
Nota: Isso determina a ordem de classificação antes que as ações sejam agrupadas e transformadas no formato Swagger. Portanto, afeta a ordem dos grupos (ou seja, "Pathitems") e a ordem das operações dentro de um grupo, na saída de arrogância.
Se o gerador encontrar o parâmetro complexo ou os tipos de resposta, ele gerará um esquema JSON correspondente, adicione -o ao dicionário de components/schemas
globais e faça referência à descrição da operação por ID exclusivo. Por exemplo, se você tiver uma ação que retorne um tipo Product
, o esquema gerado será referenciado da seguinte forma:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
No entanto, se encontrar vários tipos com o mesmo nome, mas diferentes espaços para nome (por exemplo, RequestModels.Product
& ResponseModels.Product
), o Swashbuckle aumentará uma exceção devido a "esquemaids conflitantes". Nesse caso, você precisará fornecer uma estratégia de identificação personalizada que qualifique ainda mais o nome:
Serviços.addswaggergen (c => {... c.customschemaids ((type) => type.fullName);};
Veja #2703 para obter suporte para tipos aninhados.
Exceto a caixa, o Swashbuckle faz um trabalho decente na geração de esquemas JSON que descrevem com precisão sua solicitação e carga útil. No entanto, se você estiver personalizando o comportamento de serialização para certos tipos da sua API, pode ser necessário ajudá -lo.
Por exemplo, você pode ter uma classe com várias propriedades que deseja representar no JSON como uma string separada por vírgula. Para fazer isso, você provavelmente implementaria um JsonConverter
personalizado. Nesse caso, o Swashbuckle não sabe como o conversor é implementado e você precisará fornecer um esquema que descreva com precisão o tipo:
// phonenumber.cspublic class PhoneNumber {public String countryCode {get; definir; } public string AreaCode {get; definir; } public string subscrinterid {get; definir; }} // startup.csservices.addswaggergen (c => {... c.MapType <PhoneNumber> (() => new OpenApischema {type = "String"});};
O Swashbuckle expõe um pipeline de filtro que se conecta ao processo de geração. Uma vez gerados, os objetos de metadados individuais são passados para o oleoduto, onde podem ser modificados ainda mais. Você pode conectar filtros personalizados para enriquecer as "operações", "esquemas" e "documentos" gerados.
O Swashbuckle recupera uma ApiDescription
, parte do CORE ASP.NET, para cada ação e o usa para gerar uma OpenApiOperation
correspondente. Uma vez gerado, ele passa a OpenApiOperation
e a ApiDescription
através da lista de filtros de operação configurados.
Em uma implementação típica de filtro, você inspecionaria a ApiDescription
para obter informações relevantes (por exemplo, informações da rota, atributos de ação etc.) e atualizaram a OpenApiOperation
de acordo. Por exemplo, o filtro a seguir lista uma resposta adicional "401" para todas as ações que são decoradas com o AuthorizeAttribute
:
// AuthResponsesoperationFilter.Cspublic Classe AuthResponsesoPeationFilter: IoperationFilter {public void Aplicação (Operação OpenApioperation, OperationFilterContext Context) {var Authattributes = context.methodinfo.decLaryPeM.GetCustomAtRabutes (TruextTerT.TertToToTt) e <autorizeattribute > (); if (Authattributes.any ()) Operação.Responses.add ("401", new OpenApiresponse {description = "não autorizado"});}} // startup.cssservices.addswaggergen (c => {... ... c.OperationFilter <AuthResponsesoperationFilter> ();};
NOTA: Os pipelines de filtro são di-cede. Ou seja, você pode criar filtros com parâmetros do construtor e, se os tipos de parâmetros forem registrados na estrutura DI, eles serão injetados automaticamente quando os filtros forem instanciados
O Swashbuckle gera um jsonschema com sabor de arrogância para todos os parâmetros, respostas e tipo de propriedade expostos pelas ações do seu controlador. Uma vez gerado, ele passa o esquema e digite a lista de filtros de esquema configurados.
O exemplo abaixo adiciona uma extensão de fornecedores de automóveis (consulte https://github.com/azure/autorest/blob/master/docs/extensions/readme.md#x-ms-enum) para informar a ferramenta Autorest Tool como enums deve ser modelado Quando gera o cliente da API.
// Classe AutorestsChemAfilter.Cspublic AUTORESTSCHEMAFILTER: ISCHEMAFILTER {public void Apply (OpenApischema Schema, SchemAfilterContext Context) {var Type = context.type; if (type.isenum) {schema.extensions.add ("xms- OpenApioBject {["name"] = new OpenApistring (type.name), ["Modelasstring"] = new OpenApiboolean (true)});};}} // startup.cssservices.addswaggergen (c => {... c ... c ... .SCHEMAFILTER <OTORESTSCHEMAFILTER> ();};
O exemplo abaixo permite a geração automática de esquema do Dictionary<Enum, TValue>
objetos. Observe que isso gera apenas a arrogância; System.Text.Json
não é capaz de analisar as enums do dicionário por padrão, então você precisará de um JSONCONVERTER especial, como nos documentos .NET
// dictionarytkeyenumtValuesChemAfilter.Cspublic Classe DictionaryTkeyEnumtValuesChemAfilter: IschemAfilter { Public Void Apply (esquema OpenApischema, contexto SchemAfilterContext) {// Run apenas para campos que são um dicionário <Enum, tvalue> if (! Context.type.isgenerictype ||! var keytype = context.type.getGeRerCargudes () [0]; var valuetype = context.type.getGenerericArguments () [1]; if (! keytype.isenum) {return;} schema.type = "objeto"; schema.properties = keytype.getenumnames (). Todictionary (nome => nome, nome => context.schemagenerator.generateschema (valuetype, context.schemarepository)); }} // startup.csservices.addswaggergen (c => {... // Estes serão substituídos por dictionaryTkeyEnumtValuesChemAfilter, mas são necessários para evitar um erro.// você precisará de um para todo tipo de dicionário <,> que você possui .C.MaPType <Dictionary <Myenum, List <String>>> (() => new OpenApisChema ()); C.SchemAfilter <DictionYTkeyEnumTValuesChemAfilter> ();};
Uma vez gerado um OpenApiDocument
, ele também pode ser passado através de um conjunto de filtros de documentos pré-configurados. Isso fornece controle total para modificar o documento, como você achar adequado. Para garantir que você ainda esteja retornando o Swagger JSON válido, você deve ler a especificação antes de usar esse tipo de filtro.
O exemplo abaixo fornece uma descrição para quaisquer tags atribuídas às operações no documento:
classe pública tagDescriptionsDocumentFilter: iDocumentFilter {public void Apply (OpenApidocument swaggerdoc, DocumentFilterContext Context) {swaggerdoc.tags = new List <Pomapitag> {new OpenApitag {name = "Products", "" {Name = "ordens", description = "submeter ordens"}};}}
Nota: Se você estiver usando o middleware SwaggerUI
, o TagDescriptionsDocumentFilter
demonstrado acima poderá ser usado para exibir descrições adicionais ao lado de cada grupo de operações.
Em Swagger, você pode descrever como sua API é protegida definindo um ou mais esquemas de segurança (por exemplo, Basic, API Key, OAuth2 etc.) e declarando quais desses esquemas são aplicáveis globalmente ou para operações específicas. Para mais detalhes, dê uma olhada no objeto de requisitos de segurança na especificação de arrogância.
No Swashbuckle, você pode definir esquemas invocando o método AddSecurityDefinition
, fornecendo um nome e uma instância do OpenApiSecurityScheme
. Por exemplo, você pode definir um OAuth 2.0 - Fluxo implícito da seguinte forma:
// startup.csservices.addswaggergen (c => {... // define o esquema OAuth2.0 que está em uso (ou seja, fluxo implícito) c.AddSecurityDefinition ("oauth2", new OpenApisEcurityscheMe {type = securitySchemetype.oaAuth2, fluxos = novo OpenApioAuthFlows {implícito = novo OpenApioAuthFlow {Authorizationurl = new Uri ("/auth-server/Connect/Authorize", Urikind.Relative), Scopes = New Dictionary <String, String> {{"ReadAccess", "Access Operations"}} , {"WRiteAccess", "Access Write Operations"}}}}});};
Nota: Além de definir um esquema, você também precisa indicar a quais operações esse esquema é aplicável. Você pode aplicar esquemas globalmente (ou seja, a todas as operações) através do método AddSecurityRequirement
. O exemplo abaixo indica que o esquema chamado "OAuth2" deve ser aplicado a todas as operações e que os escopos "ReadAccess" e "WriteAccess" são necessários. Ao aplicar esquemas de tipo diferente de "OAuth2", a matriz de escopos deve estar vazia.
c.addswaggergen (c => {... c.AddSecurityRenchirement (novo OpenApisEcurityRequising {{new OpenApisEcurityScheme {reference = new OpenApireference {type = referenceType.SecurityScheme, id = "oauth2"}}, new [] {"readaccess", " writeAccess "}}});})
Se você possui esquemas aplicáveis apenas a determinadas operações, poderá aplicá -las através de um filtro de operação. Por exemplo, o seguinte filtro adiciona requisitos de OAuth2 com base na presença do AuthorizeAttribute
:
// SecurityReQuirementSoperationFilter.Cspublic Classe SecurityReqüerementsOperationFilter: IoperationFilter {public void Apply (operação OpenApioperation, OperationFilterContext Context) {// Nomes de políticas Map para ScopesVar Re NeedScopes = Context.methodinfo.getCustomATRabutes (True). > attr.policy) .distinct (); if (requer withscopes.any ()) {Operação.Responses.add ("401", new OpenApiresponse {description = "não autorizado"}); operação.ronses.add ("403", novo OpenApirSponse {description = "Forbidden"}); var oauthscheme = new OpenApisEcurityscheme {reference = new OpenApireference {type = referenceType.SecurityScheme, Id = "oauth2"}}; operação.Security = new List <pearPeRementRePerment2 "}}; operação.Security = New List <BereCertIment { oauthscheme] = requernscopes.tolist ()}};}}}
Nota: Se você estiver usando o middleware SwaggerUI
, poderá ativar os fluxos interativos do OAuth2.0 que são alimentados pelos metadados de segurança emitidos. Consulte a ativação do OAuth2.0 flui para obter mais detalhes.
Serviços.addswaggergen (c => {c.addSecurityDefinition ("bearerauth", novo OpenApisEcurityScheme {type = securityschemetype.http, scheme = "portador", barerformat = "jwt", descrição "JWT Header de autorização usando o scheme de barer." );
Swagger / OpenAPI define as palavras -chave allOf
e oneOf
para descrever as relações de herança e polimorfismo nas definições de esquema. Por exemplo, se você estiver usando uma classe base para modelos que compartilham propriedades comuns, poderá usar a palavra -chave allOf
para descrever a hierarquia de herança. Ou, se o seu serializador suportar a serialização/deserialização polimórfica, você poderá usar a palavra -chave oneOf
para documentar todos os esquemas "possíveis" para solicitações/respostas que variam de acordo com o subtipo.
Por padrão, as hierarquias de herança de swashbuckle. Ou seja, para modelos derivados, as propriedades herdadas são combinadas e listadas ao lado das propriedades declaradas. Isso pode causar muita duplicação na arrogância gerada, principalmente quando há vários subtipos. Também é problemático se você estiver usando um gerador de clientes (por exemplo, NSWAG) e gostaria de manter a hierarquia de herança nos modelos de clientes gerados. Para contornar isso, você pode aplicar o cenário UseAllOfForInheritance
, e isso alavancará a palavra -chave allOf
para incorporar propriedades herdadas por referência na arrogância gerada:
Circle: { type: "object", allOf: [ { $ref: "#/components/schemas/Shape" } ], properties: { radius: { type: "integer", format: "int32", } }, }, Shape: { type: "object", properties: { name: { type: "string", nullable: true, } }, }
Se o seu serializador suportar a serialização/deserialização polimórfica e você gostaria de listar os possíveis subtipos de uma ação que aceita/retorna tipos de base abstratos, você pode aplicar a configuração de UseOneOfForPolymorphism
. Como resultado, os esquemas de solicitação/resposta gerados referenciarão uma coleção de esquemas "possíveis" em vez de apenas o esquema da classe base:
requestBody: { content: { application/json: { schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], } } }
Como os relacionamentos de herança e polimorfismo geralmente podem se tornar bastante complexos, não apenas em seus próprios modelos, mas também na biblioteca da classe .NET, o swashbuckle é seletivo sobre quais hierarquias ele faz e não expõe na arrogância gerada. Por padrão, ele captará quaisquer subtipos definidos na mesma montagem que um determinado tipo de base. Se você quiser substituir esse comportamento, pode fornecer uma função seletor personalizada:
Serviços.addswaggergen (c => {... c.UseAlLofForIritance (); c.SelectSubtypeSUsing (Basetype => {return typeof (startup) .assemly.gettypes (). where (type => type.issubclosof (bashetype); })});
NOTA: Se você estiver usando a biblioteca de anotações Swashbuckle, ele contém um seletor personalizado com base na presença de atributos SwaggerSubType
nas definições de classe base. Dessa forma, você pode usar atributos simples para listar explicitamente os relacionamentos de herança e/ou polimorfismo que deseja expor. Para permitir esse comportamento, consulte os documentos das anotações.
Em conjunto com as palavras -chave oneOf
e / ou allOf
, Swagger / OpenAPI suporta um campo discriminator
nas definições de esquema básico. Essa palavra -chave aponta para a propriedade que identifica o tipo específico representado por uma determinada carga útil. Além do nome da propriedade, a descrição do discriminador também pode incluir um mapping
que mapeia os valores do discriminador para definições específicas de esquema.
Por exemplo, o serializador do Newtonsoft suporta serialização/desserialização polimórfica emitindo/aceitando uma propriedade "$ type" nas instâncias JSON. O valor dessa propriedade será o nome do tipo qualificado da Assembléia do tipo representado por uma determinada instância JSON. Portanto, para descrever explicitamente esse comportamento em Swagger, o esquema de solicitação/resposta correspondente pode ser definido da seguinte maneira:
components: { schemas: { Shape: { required: [ "$type" ], type: "object", properties: { $type: { type": "string" }, discriminator: { propertyName: "$type", mapping: { Rectangle: "#/components/schemas/Rectangle", Circle: "#/components/schemas/Circle" } } }, Rectangle: { type: "object", allOf: [ { "$ref": "#/components/schemas/Shape" } ], ... }, Circle: { type: "object", allOf: [ { "$ref": "#/components/schemas/Shape" } ], ... } } }
Se UseAllOfForInheritance
ou UseOneOfForPolymorphism
estiver ativado e seu serializador suporta (e ativou) emitindo/aceitando uma propriedade discriminadora, o swashbuckle gerará automaticamente os metadados discriminator
correspondentes nas definições de esquema de base.
Como alternativa, se você personalizou seu serializador para apoiar a serialização/deserialização polimórfica, poderá fornecer algumas funções de seletor personalizado para determinar o nome do discriminador e o mapeamento correspondente:
Serviços.addswaggergen (c => {... c.useoneofforiRetance (); c.SelectDiscriminatorNameUsing ((Basetype) => "typename"); c.selectDiscriminatorValueUSing ((Subtype) => subtype.name);});
NOTA: Se você estiver usando a biblioteca de anotações Swashbuckle, ele contém funções seletoras personalizadas que são baseadas na presença de atributos SwaggerDiscriminator
e SwaggerSubType
nas definições de classe base. Dessa forma, você pode usar atributos simples para fornecer explicitamente metadados discriminadores. Para permitir esse comportamento, consulte os documentos das anotações.
Por padrão, a interface do usuário do Swagger será exposta em "/Swagger". Se necessário, você pode alterar isso ao ativar o middleware swaggerui:
App.USesWaggerui (C => {c.RoutePrefix = "API-DOCS"}
Por padrão, a interface do usuário do Swagger terá um título genérico de documentos. Quando você tem várias páginas de swagger abertas, pode ser difícil diferenciá -las. Você pode alterar isso ao ativar o middleware swaggerui:
App.USesWaggerui (C => {c.documenttitle = "My Swagger Ui";}
Por padrão, a interface do usuário do Swagger inclui CSS e JS padrão, mas se você deseja alterar o caminho ou o URL (por exemplo, para usar um CDN):
App.USesWaggerui (c => {c.stylespath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui.min.css"; c.scriptbundina = "https : //cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui-blardle.min.js "; c.scriptpresetspath =" https://cdnjs.cloudflare.com/ajax/libs /swagger-ui/5.17.10/swagger-ui-tandalone-preset.min.js ";}
Ao ativar o middleware, você deve especificar um ou mais pontos de extremidade de swagger (totalmente qualificados ou em relação à página da interface do usuário) para alimentar a interface do usuário. Se você fornecer vários pontos de extremidade, eles serão listados no canto superior direito da página, permitindo que os usuários alternem entre os diferentes documentos. Por exemplo, a configuração a seguir pode ser usada para documentar diferentes versões de uma API.
App.Useswaggerui (c => {c.swagegerendpoint ("/swagger/v1/swagger.json", "v1 docs"); c.swaggerEndpoint ("/swagger/v2/swagger.json", "v2 docs"); }
O Swagger-Ui é enviado com seu próprio conjunto de parâmetros de configuração, todos descritos aqui. No swashbuckle, a maioria deles é vendida pelas opções de middleware swaggerui:
App.USeswaggerui (c => {c.DefaultModeLexpandDepth (2); c.DefaultModelRerndering (ModelRndering.model); c.DefaultModelSexPandDepth (-1); c.DisplayArdId () c.disPlayPeSturation (); Nenhum); "MyCust complygin"]; ) => {resposta de retorno;} ");});
Observação
Ao adicionar plug -ins personalizados, adicione quaisquer arquivos js
personalizados que definam as funções do plug -in.
Para ajustar o comportamento, você pode injetar arquivos JavaScript adicionais adicionando -os à sua pasta wwwroot
e especificando os caminhos relativos nas opções de middleware:
App.Useswaggerui (C => {C.InjectJavaScript ("Swagger-ui/Custom.js");}
Nota: As opções InjectOnCompleteJavaScript
e InjectOnFailureJavaScript
foram removidas porque a versão mais recente do Swagger-UI não expõe os ganchos necessários. Em vez disso, fornece um sistema de personalização flexível com base em conceitos e padrões do React e Redux. Para alavancar isso, você precisará fornecer uma versão personalizada do index.html, conforme descrito abaixo.
O aplicativo de amostra de índice personalizado demonstra essa abordagem, usando o sistema de plug-in swagger-ui, fornece uma barra superior personalizada e para ocultar o componente de informações.
Para ajustar a aparência, você pode injetar folhas de estilo CSS adicionais adicionando -as à sua pasta wwwroot
e especificando os caminhos relativos nas opções de middleware:
App.Useswaggerui (c => {c.injectstylesheet ("/swagger-ui/custom.css");}
Para personalizar a interface do usuário além das opções básicas listadas acima, você pode fornecer sua própria versão da página Swagger-Ui Index.html:
App.USesWaggerui (C => {c.IndexStream = () => getType (). Assembly .getManifestResourceStream ("Customuiindex.swagger.index.html"); // requer arquivo para ser adicionado como um recurso incorporado});
Para começar, você deve basear seu index.html personalizado na versão padrão
O Swagger-Ui tem suporte integrado para participar dos fluxos de autorização OAuth2.0. Ele interage com a autorização e/ou terminais de token, conforme especificado no Swagger JSON, para obter tokens de acesso para as chamadas de API subsequentes. Consulte Adicionando definições e requisitos de segurança para um exemplo de adição de metadados OAuth2.0 à arrogância gerada.
Se o seu ponto final de swagger incluir os metadados de segurança apropriados, a interação da interface do usuário deverá ser ativada automaticamente. No entanto, você pode personalizar ainda mais o suporte da OAuth na interface do usuário com as seguintes configurações abaixo. Consulte Documentação Swagger-UI para obter mais informações:
App.Useswaggerui (c => {c.oauthclientId ("teste-id"); c.oauthclientSecret ("teste-secret"); c.oauthusername ("test-user"); c.oauthrealm ("test-reenalm" ); String, String> {{"foo", "bar"}});
Para usar interceptores personalizados, mediante solicitações e respostas, passando por Swagger-UI, você pode defini-las como funções JavaScript na configuração:
App.Useswaggerui (c => {c.UseReQuestInterceptor ("(req) => {req.headers ['x-my-clustom-header'] = 'myCustomValue'; retornar req;}"); c.UserSponsoSoScept (" (res) => {console.log ('Resposta interceptada personalizada de:', res.url);
Isso pode ser útil em uma série de cenários em que você pode querer anexar tokens XSRF local a todos os pedidos, por exemplo:
App.Useswaggerui (c => {c.UseReQuestIntercept ("(req) => {req.headers ['x-xsrf-token'] = localStorage.getItem ('xsrf-token'); retornar req;}"); });
Instale o seguinte pacote NUGET no seu aplicativo ASP.NET CORE.
Package Manager : Install-Package Swashbuckle.AspNetCore.Annotations CLI : dotnet add package Swashbuckle.AspNetCore.Annotations
No método ConfigureServices
do Startup.cs
, ative anotações no bloco de configuração do Swagger:
serviços.addswaggergen (c => {... c.enableannotações ();});
Depois que as anotações forem ativadas, você pode enriquecer os metadados de operação gerados decorando ações com um SwaggerOperationAttribute
.
[Httppost] [swaggeroperation (summary = "cria um novo produto", description = "requer privilégios de administrador", OperationId = "CreateProduct", tags = new [] {"compra", "Products"})] public iactionResult Create ([[[[[ Frombody] Produto Produto)
O ASP.NET Core fornece o ProducesResponseTypeAttribute
para listar as diferentes respostas que podem ser retornadas por uma ação. Esses atributos podem ser combinados com os comentários XML, como descrito acima, para incluir descrições amigáveis ao humano com cada resposta na arrogância gerada. Se você preferir fazer tudo isso com um único atributo e evite o uso de comentários XML, você pode usar SwaggerResponseAttribute
S:
[Httppost] [SwaggerResponse (201, "O produto foi criado", tipoof (Produto)]] [SwaggerResponse (400, "Os dados do produto são inválidos")]
Você pode anotar parâmetros ou propriedades vinculados ao "caminho", "consulta" ou "cabeçalho" (ou seja, decorados com [FromRoute]
, [FromQuery]
ou [FromHeader]
) com um SwaggerParameterAttribute
para enriquecer os metadados Parameter
correspondentes gerados pelo swashbuckle:
[Httpget] public iactionResult getProducts ([FORMQUERY, SwaggerParameter ("Pesquisa Palavras -chave", requerir = true)] String Palavras -chave)
Você pode anotar parâmetros ou propriedades vinculadas ao "corpo" (ou seja, decorado com [FromBody]
) com um SwaggerRequestBodyAttribute
para enriquecer os metadados RequestBody
correspondentes que são gerados pelo Swashbuckle:
[Httppost] Public IActionResult CreateProduct ([Frombody, SwaggerRequestbody ("A carga útil do produto", requerir = true)] Produto do produto)
Você pode anotar classes ou propriedades com um SwaggerSchemaAttribute
para enriquecer os metadados Schema
correspondentes que são gerados pelo Swashbuckle:
[Swaggerschema (obrigatório = new [] {"description"})] public class Product {[swaggerschema ("o identificador do produto", readonly = true)] public int id {get; definir; } [Swaggerschema ("a descrição do produto")] public string description {get; definir; } [Swaggerschema ("a data em que foi criada", format = "date")] public DateTime DateCreated {get; definir; }}
Nota: Em Swagger / OpenAPI, objetos serializados e propriedades contidas são representadas como instâncias Schema
, por isso essa anotação pode ser aplicada a classes e propriedades. Também vale a pena notar, as propriedades "necessárias" são especificadas como uma variedade de nomes de propriedades no esquema de nível superior, em oposição a uma bandeira em cada propriedade individual.
O pacote SwaggerGen
fornece vários pontos de extensão, incluindo filtros de esquema (descritos aqui) para personalizar todos os esquemas gerados. No entanto, pode haver casos em que é preferível aplicar um filtro a um esquema específico. Por exemplo, se você quiser incluir um exemplo para um tipo específico na sua API. Isso pode ser feito decorando o tipo com um SwaggerSchemaFilterAttribute
:
// Product.cs [swaggerschemAfilter (typeof (producschemafilter)]] public class Product {...} // ProductsChemAfilter.cspublic class ProductsChemafilter: isChemAfilter {Void publicitário Aplicação (Schema OpenApischema, SchemafilterConteContext) {Schema. ["Id"] = new OpenApiInteger (1), ["Descrição"] = new OpenApistring ("um produto incrível")};}}
Por padrão, o gerador de swagger marcará todas as operações com o nome do controlador. Esta tag é usada para acionar os agrupamentos de operações no Swagger-UI. Se você deseja fornecer uma descrição para cada um desses grupos, pode fazê -lo adicionando metadados para cada tag de nome do controlador por meio do SwaggerTagAttribute
:
[Swaggertag ("Criar, ler, atualizar e excluir produtos")] Public Class ProductScontroller {...}
NOTA: Isso adicionará a descrição acima especificamente à tag chamada "Produtos". Portanto, você deve evitar usar esse atributo se estiver marcando operações com algo diferente do nome do controlador - por exemplo, se você estiver personalizando o comportamento de marcação com TagActionsBy
.
Se você deseja usar o comportamento de herança e/ou polimorfismo do Swashbuckle, pode usar anotações para indicar explicitamente os subtipos "conhecidos" para um determinado tipo de base. Isso substituirá a função seletor padrão, que seleciona todos os subtipos na mesma montagem que o tipo base e, portanto, precisa ser explicitamente ativado ao ativar anotações:
// startup.csservices.addswaggergen (c => {c.enableanNoTações (enabaneações para financiamento: true, enableanNoTationsForpolymorphism: true);}); // shape.cs [swaggersubtype (retângulo); ] forma de classe abstrata pública {}
Se você estiver usando anotações para indicar explicitamente os subtipos "conhecidos" para um tipo de base polimórfica, combina o SwaggerDiscriminatorAttribute
com o SwaggerSubTypeAttribute
para fornecer metadados adicionais sobre a propriedade "discriminador", que será incorporada à definição gerada de esquema:
// startup.csservices.addswaggergen (c => {c.enableanNoTações (enabaneianotações parainheritância: true, enableanNoTationsForpolymorphism: true);}); // shape.cs [swaggerdiscriminator ("shapetype")] [swagersptyptypei (swaggerdiscriminator ("shapetype")] [swagpersptypypei. = "Rectangle")] [swaggersubtype (typeof (círculo), discriminatorValue = "circ")] public abstray class Shape {public shapeType {get; definir; }}
Isso indica que a carga útil correspondente terá uma propriedade "Shapetype" para discriminar entre subtipos, e essa propriedade terá um valor de "retângulo" se a carga útil representar um tipo Rectangle
e um valor de "círculo" se representar um tipo Circle
. Este detalhe será descrito na definição de esquema gerado da seguinte maneira:
schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], discriminator: { propertyName: shapeType, mapping: { rectangle: "#/components/schemas/Rectangle", circle: "#/components/schemas/Circle", } } }
Depois que seu aplicativo tiver sido configurado com o Swashbuckle (consulte o início), você pode usar a ferramenta CLI Swashbuckle para recuperar o Swagger / OpenAPI JSON diretamente da montagem de inicialização do seu aplicativo e escrevê -lo no arquivo. Isso pode ser útil se você deseja incorporar a geração de swagger em um processo de CI/CD ou se desejar servir a partir de arquivo estático em tempo de execução.
É embalado como uma ferramenta .NET que pode ser instalada e usada através do DOTNET SDK.
️ A ferramenta precisa carregar sua DLL de inicialização e suas dependências em tempo de execução. Portanto, você deve usar uma versão dodotnet
SDK compatível com seu aplicativo. Por exemplo, se o seu aplicativo segmentarnet6.0
, você deverá usar a versão 6.0.xxx do SDK para executar a ferramenta CLI. Se ele tem como alvonet8.0
, você deve usar a versão 8.0.xxx do SDK e assim por diante.
Instale como uma ferramenta global
dotnet tool install -g Swashbuckle.AspNetCore.Cli
Verifique se a ferramenta foi instalada corretamente
swagger tofile --help
Gere um documento de arrogância/ openapi na montagem de inicialização do seu aplicativo
swagger tofile --output [output] [startupassembly] [swaggerdoc]
Onde ...
[Saída] é o caminho relativo onde o Swagger JSON será produzido para
[Startupassembly] é o caminho relativo para a montagem de inicialização do seu aplicativo
[swaggerdoc] é o nome do documento Swagger que você deseja recuperar, conforme configurado em sua aula de inicialização
Na sua raiz do projeto, crie um arquivo de manifesto de ferramenta:
dotnet new tool-manifest
Instale como uma ferramenta local
dotnet tool install Swashbuckle.AspNetCore.Cli
Verifique se a ferramenta foi instalada corretamente
dotnet swagger tofile --help
Gere um documento de arrogância / openapi na montagem de inicialização do seu aplicativo
dotnet swagger tofile --output [output] [startupassembly] [swaggerdoc]
Onde ...
[Saída] é o caminho relativo onde o Swagger JSON será produzido para
[Startupassembly] é o caminho relativo para a montagem de inicialização do seu aplicativo
[swaggerdoc] é o nome do documento Swagger que você deseja recuperar, conforme configurado em sua aula de inicialização
Pronto para a caixa, a ferramenta será executada no contexto de um host "padrão". No entanto, em alguns casos, você pode querer trazer seu próprio ambiente de host, por exemplo, se você configurou um contêiner DI personalizado, como o Autofac. Para esse cenário, a ferramenta CLI Swashbuckle expõe um gancho baseado em convenções para o seu aplicativo.
Ou seja, se o seu aplicativo contiver uma classe que atingir uma das seguintes convenções de nomenclatura, essa classe será usada para fornecer um host para a ferramenta CLI ser executada.
public class SwaggerHostFactory
, contendo um método estático público chamado CreateHost
com o retorno tipo IHost
public class SwaggerWebHostFactory
, contendo um método estático público chamado CreateWebHost
com o retorno tipo IWebHost
Por exemplo, a aula a seguir pode ser usada para aproveitar a mesma configuração do host que seu aplicativo:
classe pública swaggerhostfactory {public static ihost createHost () {return program.createhostbuilder (new string [0]). build ();}}
Por padrão, a interface do usuário Redoc será exposta em "/API-DOCs". Se necessário, você pode alterar isso ao ativar o middleware Redoc:
App.UserEdoc (C => {c.RoutePrefix = "Docs" ...}
Por padrão, a interface do usuário Redoc terá um título genérico de documentos. Você pode alterar isso ao ativar o middleware Redoc:
App.UserEdoc (c => {c.documentTitle = "My API Docs"; ...}
A Redoc é fornecida com seu próprio conjunto de parâmetros de configuração, todos descritos aqui https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object. No swashbuckle, a maioria deles é vendida através das opções de middleware Redoc:
App.UserEdoc (c => {c.specurl ("/v1/swagger.json"); c.enableuntrustedSpec (); c.crollyoffset (10); c.hidehostname (); c.hidedwnloadbutton (); c.expondresponses (200,201 "); SortPropsalphabeticicamente ();});
O uso de c.SpecUrl("/v1/swagger.json")
várias vezes no mesmo UseReDoc(...)
não adicionará vários URLs.
Para ajustar a aparência, você pode injetar folhas de estilo CSS adicionais adicionando -as à sua pasta wwwroot
e especificando os caminhos relativos nas opções de middleware:
App.UserEdoc (C => {... C.InjectStylesheet ("/Redoc/Custom.css");}
Também é possível modificar o tema usando a propriedade AdditionalItems
, consulte https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object para obter mais informações.
App.UserEdoc (c => {... c.configobject.additionitemss = ...}
Para personalizar a interface do usuário além das opções básicas listadas acima, você pode fornecer sua própria versão da página Redoc Index.html:
App.UserEdoc (c => {c.IndexStream = () => getType (). Assembly .getManifestResourCestream ("CustomIndex.redoc.index.html"); // Requer que o arquivo seja adicionado como um recurso incorporado});
Para começar, você deve basear seu index.html personalizado na versão padrão