¡Aviso importante si está actualizando entre las versiones principales! |
---|
* Si está actualizando de 4.x a 5.x, hay varios cambios de ruptura a tener en cuenta. Vea las notas de la versión para más detalles * Si está haciendo el salto de 3.x a 4.x primero, también hay dragones allí. Vea esas notas de lanzamiento aquí |
Herramientas de arrogancia para API construidas con ASP.NET Core. Genere una hermosa documentación de API, incluida una interfaz de usuario para explorar y probar operaciones, directamente desde sus rutas, controladores y modelos.
Además de su generador Swagger 2.0 y Openapi 3.0, Swashbuckle también proporciona una versión incrustada del increíble Swagger-UI que funciona con el Swagger JSON generado. Esto significa que puede complementar su API con la documentación viva que siempre está sincronizada con el último código. Lo mejor de todo es que requiere una codificación y mantenimiento mínimas, lo que le permite concentrarse en construir una API increíble.
Y eso no es todo ...
Una vez que tenga una API que pueda describirse en Swagger, ha abierto el cofre del tesoro de las herramientas basadas en Swagger, incluido un generador de clientes que puede dirigirse a una amplia gama de plataformas populares. Vea Swagger-Codegen para más detalles.
Versión de 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 el paquete NUGET estándar en su aplicación ASP.NET Core.
Package Manager : Install-Package Swashbuckle.AspNetCore CLI : dotnet add package Swashbuckle.AspNetCore
En el método ConfigureServices
de Startup.cs
, registre el generador Swagger, definiendo uno o más documentos de Swagger.
usando Microsoft.openapi.Models;
Services.Addmvc (); Services.addsWaggerGen (c => {C.SwaggerDoc ("V1", new OpenApiInfo {title = "My API", Version = "V1"});});
Asegúrese de que sus acciones y parámetros de API estén decorados con enlaces explícitos "http" y "de".
[Httppost] public void createProduct ([frombody] producto producto) ...
[Httpget] public IEnumerable <Product> SearchProducts ([fromQuery] Palabras clave de cadena) ...
Nota: Si omite los enlaces de parámetros explícitos, el generador los describirá como parámetros de "consulta" de forma predeterminada.
En el método Configure
, debe exponer la arrogancia generada como punto final JSON por uno de los siguientes métodos:
app.mapendpoints (endpoints => {// ... endpoints.mapswagger ();});
App.UseSWagger ();
En este punto, puede girar su aplicación y ver el Swagger JSON generado en "/swagger/v1/swagger.json".
Insertar middleware
Agregue los puntos finales si está utilizando el enrutamiento basado en el punto final.
Opcionalmente, inserte el middleware Swagger-UI si desea exponer la documentación interactiva, especificando los puntos finales JSON Swagger para impulsarla.
App.UseSWaggerUi (c => {C.SwaggerEndpoint ("V1/Swagger.json", "My API V1");});
Ahora puede reiniciar su aplicación y consultar los documentos interactivos e interactivos generados automáticamente en "/Swagger".
En versiones anteriores a 5.0.0
, Swashbuckle generará esquema (descripciones de los tipos de datos expuestos por una API) basado en el comportamiento del serializador de Newtonsoft . Esto tenía sentido porque ese era el serializador que se envió con ASP.NET Core en ese momento. Sin embargo, desde la versión 3.0.0
, ASP.NET Core presenta un nuevo serializer System.Text.Json (STJ) fuera de la caja, y si desea continuar utilizando Newtonsoft , debe instalar un paquete separado y explícitamente optada. De Swashbuckle 5.0.0
y más allá de un patrón similar se usa. Es decir, Swashbuckle listo para usar, asumirá que está utilizando el serializador STJ y generará esquemas en función de su comportamiento. Si está utilizando Newtonsoft , deberá instalar un paquete Swashbuckle separado y optar explícitamente. Este es un paso requerido, independientemente de qué versión de ASP.NET Core que esté utilizando .
En resumen ...
Si está utilizando System.Text.Json (STJ) , la configuración descrita anteriormente será suficiente, y el generador Swagger honrará automáticamente las opciones/atributos STJ .
Si está utilizando Newtonsoft , deberá instalar un paquete separado y optar explícitamente para asegurarse de que el generador Swagger honra automáticamente los ajustes/atributos de Newtonsoft :
Package Manager : Install-Package Swashbuckle.AspNetCore.Newtonsoft CLI : dotnet add package Swashbuckle.AspNetCore.Newtonsoft
Services.addmvc (); Services.addsWaggerGen (c => {C.SwaggerDoc ("V1", new OpenApiInfo {title = "My API", Version = "V1"});}); Services.addswaggergennewtonsoftSupport (); // Opt -In Explicit - debe colocarse después de addswaggergen ()
Swashbuckle se basa en gran medida en ApiExplorer
, la capa de metadatos API que se envía con ASP.NET Core. Si está utilizando el Helper AddMvc
para arrancar la pila MVC, entonces Apiexplorer se registrará automáticamente y SB funcionará sin problemas. Sin embargo, si está utilizando AddMvcCore
para una pila MVC más emparejada, deberá agregar explícitamente el servicio ApiExplorer:
Services.AddMVCCore (). Addapiexplorer ();
Además, si está utilizando el enrutamiento convencional (a diferencia del enrutamiento de atributos), cualquier controlador y las acciones en aquellos controladores que usan enrutamiento convencional no se representarán en ApiExplorer, lo que significa que Swashbuckle no podrá encontrar esos controladores y generar Swagger operaciones de ellos. Por ejemplo:
app.usemvc (rutas => {// swaggergen no encontrará controladores enrutados a través de esta técnica. Routes.maproute ("default", "{controlador = home}/{Action = index}/{id?}") ;});
Debe usar el enrutamiento de atributos para cualquier controlador que desee representado en sus documentos Swagger:
[Route ("Ejemplo")] Public Class Expplecontroller: Controller {[httpget ("")] public IActionResult Dostuff () { / ** /}}
Consulte la documentación de enrutamiento para obtener más información.
Swashbuckle consta de múltiples componentes que se pueden usar juntos o individualmente dependiendo de sus necesidades. En esencia, hay un generador de arrogancia, middleware para exponerlo como puntos finales JSON y una versión empaquetada del Swagger-UI. Estos 3 paquetes se pueden instalar con Swashbuckle.AspNetCore
"Metapackage" y funcionarán juntos sin problemas (ver comenzando) para proporcionar hermosos documentos de API que se generan automáticamente a partir de su código.
Además, hay paquetes de complementos (herramientas CLI, una interfaz de usuario alternativa, etc.) que opcionalmente puede instalar y configurar según sea necesario.
Paquete | Descripción |
---|---|
Swashbuckle.aspnetcore.swagger | Expone los puntos finales JSON Swagger. Espera que se registre una implementación de ISwaggerProvider en el contenedor DI, que consulta para recuperar OpenAPIDocument(s) que luego se expusen como JSON serializado |
Swashbuckle.aspnetcore.swaggergen | Inyecta una implementación de ISwaggerProvider que puede ser utilizado por el componente anterior. Esta implementación particular genera OpenApiDocument(s) de sus rutas, controladores y modelos |
Swashbuckle.aspnetcore.swaggerui | Expone una versión incrustada del Swagger-UI. Usted especifica los puntos finales de la API donde puede obtener Swagger JSON, y los usa para encender documentos interactivos para su API |
Paquete | Descripción |
---|---|
Swashbuckle.aspnetcore.annotaciones | Incluye un conjunto de atributos personalizados que se pueden aplicar a controladores, acciones y modelos para enriquecer la arrogancia generada |
Swashbuckle.aspnetcore.cli | Proporciona una interfaz de línea de comandos para recuperar Swagger directamente de un ensamblaje de inicio y escribir en archivos |
Swashbuckle.aspnetcore.Rredoc | Expone una versión incrustada de la ui redoc (una alternativa a Swagger-UI) |
Estos paquetes son proporcionados por la comunidad de código abierto.
Paquete | Descripción |
---|---|
Swashbuckle.aspnetcore.filters | Algunos filtros útiles de Swashbuckle que agregan documentación adicional, EG Solicitud y ejemplos de respuesta, información de autorización, etc. Consulte su Readme para obtener más detalles |
Unchase.swashbuckle.aspnetcore.extensions | Algunas extensiones útiles (filtros), que agregan documentación adicional, por ejemplo, ocultar pathitems para roles inaceptados, arreglar enums para la generación de código del cliente, etc. Consulte su lectura para obtener más detalles |
Microelementos.swashbuckle.fluentvalidation | Utilice las reglas de Validación Fluent en lugar de los atributos del modelo componente al aumento de esquemas de arrogancia generados |
Mmlib.swaggerforocelot | Documentaciones agregadas sobre microservicios directamente en la puerta de enlace de la API de Ocelot |
Los pasos descritos anteriormente lo pondrán en funcionamiento con una configuración mínima. Sin embargo, Swashbuckle ofrece mucha flexibilidad para personalizar como mejor le parezca. Consulte la tabla a continuación para ver la lista completa de opciones:
Swashbuckle.aspnetcore.swagger
Cambiar el camino para los puntos finales de Swagger JSON
Modificar swagger con contexto de solicitud
Serialize swagger json en el formato 2.0
Trabajar con directorios virtuales y proxies inversos
Personalización de cómo se está serializado el documento OpenApi
Swashbuckle.aspnetcore.swaggergen
Asignar operadores explícitos
Respuestas de operaciones de lista
Los parámetros requeridos por la bandera y las propiedades de esquema
Manejar formularios y cargas de archivos
Manejar descargas de archivos
Incluir descripciones de comentarios XML
Proporcionar metadatos de API globales
Generar múltiples documentos de arrogancia
Omita operaciones obsoletas y/o propiedades de esquema
Omitir operaciones arbitrarias
Personalizar etiquetas de operación (por ejemplo, para agrupar UI)
Cambiar el orden de clasificación de operación (por ejemplo, para la clasificación de la interfaz de usuario)
Personalizar ID de esquema
Anular el esquema para tipos específicos
Extender el generador con filtros de operación, esquema y documentos
Agregar definiciones y requisitos de seguridad
Agregar definiciones y requisitos de seguridad para la autenticación Bearer
Herencia y polimorfismo
Swashbuckle.aspnetcore.swaggerui
Cambiar el camino relativo a la interfaz de usuario
Cambiar título de documento
Cambiar las rutas CSS o JS
Enumere múltiples documentos de arrogancia
Aplicar parámetros Swagger-UI
Inyectar JavaScript personalizado
Inyectar CSS personalizado
Personalizar index.html
Habilitar flujos OAuth2.0
Utilice interceptores de solicitudes e respuesta del lado del cliente
Swashbuckle.aspnetcore.annotaciones
Instalar y habilitar anotaciones
Enriquecer los metadatos de operación
Enriquecer los metadatos de respuesta
Enriquecer metadatos de parámetros
EnrichlyBody Metadatos
Enriquecer metadatos de esquema
Aplicar filtros de esquema a tipos específicos
Agregar metadatos de etiqueta
Swashbuckle.aspnetcore.cli
Recupere Swagger directamente de una asamblea de inicio
Use la herramienta CLI con una configuración de host personalizada
Swashbuckle.aspnetcore.Rredoc
Cambiar el camino relativo a la interfaz de usuario
Cambiar título de documento
Aplicar parámetros redoc
Inyectar CSS personalizado
Personalizar index.html
Por defecto, Swagger JSON se expusirá en la siguiente ruta: "/swagger/{DocumentNamehyH/swagger.json". Si es necesario, puede cambiar esto al habilitar el middleware Swagger. Las rutas personalizadas deben incluir el parámetro {documentName}
.
App.UseSWagger (c => {c.RoutetEmplate = "API-DOCS/{DocumentName} /Swagger.json";})
Nota: Si está utilizando el middleware Swaggerui, también deberá actualizar su configuración para reflejar los nuevos puntos finales:
App.UseSWaggerUi (c => {C.SwaggerEndpoint ("/API-DOCS/V1/Swagger.json", "My API V1");})
Nota: Si también necesita actualizar la ruta relativa en la que la IU en sí está disponible, deberá seguir las instrucciones que se encuentran en la ruta relativa de cambio a la interfaz de usuario.
Si necesita establecer algunos metadatos de Swagger en función de la solicitud actual, puede configurar un filtro que se ejecuta antes de serializar el documento.
App.UseSWagger (c => {C.PreserializeFilters.Add ((swagger, httpreq) => {swagger.servers = nueva lista <enenapiserver> {new OpenApiserver {url = $ "{httpreq.scheme}: // {httpreq. Host.value} "}};});});
OpenApiDocument
y HttpRequest
actual se pasan al filtro. Esto proporciona mucha flexibilidad. Por ejemplo, puede agregar un servidor API explícito basado en el encabezado "Host" (como se muestra), o puede inspeccionar la información de la sesión o un encabezado de autorización y eliminar las operaciones del documento basado en los permisos de los usuarios.
Por defecto, Swashbuckle generará y expondrá Swagger JSON en la versión 3.0 de la especificación, llamada oficialmente la especificación de OpenAPI. Sin embargo, para admitir la compatibilidad hacia atrás, puede optar por continuar exponiéndolo en el formato 2.0 con la siguiente opción:
App.UseSWagger (c => {C.SerializeAsv2 = true;});
Los directorios virtuales y los proxies inversos pueden causar problemas para las aplicaciones que generan enlaces y redireccionamientos, particularmente si la aplicación devuelve URL absolutas en función del encabezado Host
y otra información de la solicitud actual. Para evitar estos problemas, Swashbuckle usa URL relativas cuando sea posible y alienta su uso al configurar el swaggerui y el middleware redoc.
Por ejemplo, para conectar el middleware Swaggerui, proporciona la URL a uno o más documentos de OpenApi/Swagger. Esta es la URL que Swagger-UI, una aplicación del lado del cliente, llamará para recuperar sus metadatos de API. Para garantizar que esto funcione detrás de los directorios virtuales y los proxies inversos, debe expresar esto en relación con el RoutePrefix
del propio Swagger-UI:
App.UseSWaggerUi (c => {c.RoutePrefix = "swagger"; c.swaggerEndpoint ("v1/swagger.json", "mi api v1");});
Nota: En versiones anteriores de los documentos, es posible que haya visto esto expresado como un enlace relativo a la raíz (por ejemplo, /swagger/v1/swagger.json
). Esto no funcionará si su aplicación está alojada en un directorio virtual IIS o detrás de un proxy que recorta la ruta de solicitud antes de reenviar. Si cambia a la sintaxis relativa a la página que se muestra arriba, debería funcionar en todos los casos.
De forma predeterminada, SwashBuckle serializará el documento OpenAPI utilizando los métodos de serialización en el objeto del documento OpenAPI. Si se desea una serialización personalizada, es posible crear un serializador de documentos personalizado que implementa la interfaz ISwaggerDocumentSerializer
. Esto se puede configurar en las SwaggerOptions
en la colección de servicios utilizando ConfigureSwagger()
::
Nota
Si planea usar la herramienta de línea de comandos para generar archivos de especificación de OpenAPI, esto debe hacerse en la colección de servicios utilizando ConfigureSwagger()
.
Services.ConfiguesWagger (Options => {option.SetCustomDocumentSerializer <CustomDocumentSerializer> ();})
Cuando no se usa la herramienta de línea de comandos, también se puede hacer en el host de aplicación:
App.UseSWagger (options => {options.setCustomDocumentserializer <CustomDocumentSerializer> ();})
En Swagger, a las operaciones se les puede asignar un operationId
. Esta identificación debe ser única entre todas las operaciones descritas en la API. Las herramientas y las bibliotecas (por ejemplo, los generadores de clientes) pueden usar el operatorID para identificar de manera única una operación, por lo tanto, se recomienda seguir convenciones de nombres de programación comunes.
La generación automática de una ID que coincide con estos requisitos, al tiempo que proporciona un nombre que sería significativo en las bibliotecas de clientes es una tarea no trivial y, por lo tanto, SwashBuckle omite el operationId
de forma predeterminada. Sin embargo, si es necesario, puede asignar operationIds
decorando rutas individuales o proporcionando una estrategia personalizada.
Opción 1) Decorar rutas con una propiedad Name
[Httpget ("{id}", name = "getProductById")] public IActionResult get (int id) // operationId = "getProductById"
Opción 2) Proporcionar una estrategia personalizada
// startup.csservices.addswaggergen (c => {... // use el nombre del método como operationId c.customoperationIds (apidesc => {return apidesc.trygetmethodinfo (Out MethodInfo MethodInfo)? MethodInfo.name: Null;});} ) // ProductScontroller.cs [httpget ("{id}")] public IActionResult getProductById (int id) // operationId = "getProductById"
Nota: Con cualquier enfoque, los autores de la API son responsables de garantizar la singularidad de operationIds
en todas las operaciones
Por defecto, Swashbuckle generará una respuesta "200" para cada operación. Si la acción devuelve una respuesta DTO, esto se usará para generar un esquema para el cuerpo de respuesta. Por ejemplo ...
[Httppost ("{id}")] producto público getByid (int id)
Producirá los siguientes metadatos de respuesta:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
Si necesita especificar un código de estado diferente y/o respuestas adicionales, o sus acciones devuelven IActionResult
en lugar de una respuesta DTO, puede describir explícitamente las respuestas con el ProducesResponseTypeAttribute
que se envía con ASP.NET Core. Por ejemplo ...
[Httppost ("{id}")] [producirResponseSetype (typeof (producto), 200)] [producirResponseSetype (typeof (idiculary <string, string>), 400)] [ProducesResponseType (500)] Public IcactionResult GetByid (int)
Producirá los siguientes metadatos de respuesta:
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: {} } }
En un documento de arrogancia, puede marcar parámetros y propiedades de esquema que se requieren para una solicitud. Si un parámetro (de nivel superior o basado en propiedad) está decorado con BindRequiredAttribute
o RequiredAttribute
, entonces SwashBuckle lo marcará automáticamente como un parámetro "requerido" en el Swagger generado:
// ProductsController.cspublic IActionResult Search ([fromQuery, bindRequired] String Keywords, [fromQuery] PagingParams PagingParams) {if (! ModelState.ISValid) return BadRequest (modelState); ...} // SearchParams.Cpublic class PagingParams {[requerido ] public int pageno {get; colocar; } public int PAGESIZE {get; colocar; }}
Además de los parámetros, Swashbuckle también honrará el RequiredAttribute
cuando se use en un modelo que está vinculado al cuerpo de solicitud. En este caso, las propiedades decoradas se marcarán como propiedades "requeridas" en la descripción del cuerpo:
// ProductScontroller.cspublic iActionResult create ([fromBody] Product Product) {if (! ModelState.IsValid) return badRequest (modelState); ...} // producto. Cspublic Product {[requerido] Nombre de cadena pública {Get; colocar; } Descripción de cadena pública {get; colocar; }}
Este controlador aceptará dos valores de campo de formulario y una carga de archivo con nombre de la misma forma:
[Httppost] public void uploadFile ([fromform] string description, [fromform] dateTime ClientDate, archivo iformfile)
Nota importante: Según los documentos del núcleo ASP.NET, no se supone que decore los parámetros
IFormFile
con el atributo[FromForm]
como la fuente de enlace se infiere automáticamente del tipo. De hecho, el valor inferido esBindingSource.FormFile
y si aplica el atributo se establecerá enBindingSource.Form
en su lugar, que arruinaApiExplorer
, el componente de metadatos que envía con núcleo ASP.NET y se basa en gran medida por SwashBuckle. Un problema en particular aquí es que Swaggerui no tratará el parámetro como un archivo y, por lo tanto, no mostrará un botón de carga de archivo, si incluye por error este atributo.
ApiExplorer
(el componente de metadatos de Core ASP.NET en el que se basa Swashbuckle) no surge los tipos FileResult
por defecto y, por lo tanto, debe decirlo explícitamente con el atributo ProducesResponseType
(o Produces
.NET 5 o anterior):
[Httpget ("{FileName}")] [ProducesSponseSetype (typeof (fileStreamResult), statusCodes.status200ok, "Image/jpeg")] Public FileStreamResult getFile (String filename)
Para mejorar los documentos generados con descripciones amigables para los humanos, puede anotar acciones y modelos del controlador con comentarios XML y configurar Swashbuckle para incorporar esos comentarios en el Swagger JSON emitido:
Abra el cuadro de diálogo Propiedades para su proyecto, haga clic en la pestaña "Construir" y asegúrese de que se verifique el "archivo de documentación XML", o agregue <GenerateDocumentationFile>true</GenerateDocumentationFile>
elemento a la sección <PropertyGroup>
de su archivo del proyecto .csproj. Esto producirá un archivo que contiene todos los comentarios XML en el tiempo de compilación.
En este punto, cualquier clases o métodos que no se anoten con comentarios XML activarán una advertencia de compilación. Para suprimir esto, ingrese el código de advertencia "1591" en el campo "Suprimante advertencias" en el cuadro de diálogo Propiedades o agregue <NoWarn>1591</NoWarn>
a la sección <PropertyGroup>
de su archivo de proyecto .csproj.
Configure SwashBuckle para incorporar los comentarios XML en el archivo en el Swagger JSON generado:
Services.addswaggerGen (c => {C.SwaggerDoc ("V1", new OpenApiInfo {title = "My API - V1", Version = "V1"}); C.includexmlComments (Assembly.getExeCutingAsmbly (); / o c.includexmlcomments (typeof (myController) .Assembly));}
Anotar sus acciones con resumen, observaciones, parámetros y etiquetas de respuesta:
/// <summary> /// Recupera un producto específico por ID único /// </summary> /// <sements> awesomeness! </observación> /// <param name = "id" ejemplo = "123" > El ID de producto </amamr> /// <respuesta código = "200"> Producto recuperado </respuesta> /// <respuesta código = "404"> Producto no encontrado </respuesta> /// <Response Code = "500"> ¡Ups! No puedo buscar su producto en este momento </spuesta> [httpget ("{id}")] [producirResponseSetype (typeof (producto), 200)] [ProducesSponseSetype (404)] [ProducesSponseSetype (500)] Producto público GetByID (int GetByID (int GetByid identificación)
También puede anotar tipos con resumen y etiquetas de ejemplo:
Producto de clase pública {//// <summary> /// El nombre del producto /// </summary> /// <sample> zapatos de baloncesto masculino </ejemplo> nombre de cadena public {get; colocar; } /// <summary> /// Cantidad izquierda en stock /// </summary> /// <scample> 10 </scuestor> public intoLeableStock {get; colocar; } /// <summary> /// Los tamaños del producto están disponibles en /// </summary> /// <cectual> ["pequeño", "mediano", "grande"] </ejemplo> lista pública < cadena> tamaños {get; colocar; }}
Reconstruya su proyecto para actualizar el archivo de comentarios XML y navegar al punto final Swagger JSON. Tenga en cuenta cómo se asignan las descripciones en los campos de arrogancia correspondientes.
Nota: También puede proporcionar descripciones de esquema de arrogancia anotando sus modelos API y sus propiedades con etiquetas de resumen. Si tiene múltiples archivos de comentarios XML (por ejemplo, bibliotecas separadas para controladores y modelos), puede invocar el método incluirxmlComments varias veces y todos se fusionarán en el swagger JSON.
Además de "Pathitems", "Operaciones" y "respuestas", que Swashbuckle genera para usted, Swagger también admite metadatos globales (ver https://swagger.io/specification/#oasobject). Por ejemplo, puede proporcionar una descripción completa de su API, términos de servicio o incluso información de contacto y licencia:
C.SwaggerDoc ("V1", nuevo OpenApiInfo {title = "My API - V1", versión = "V1", Descripción = "Una API de muestra para demo SwashBuckle", TermemOfService = New Uri ("http://tempuri.org.org.org /Términos "), contact = new OpenApiContact {name =" Joe Developer ", Correo electrónico =" [email protected] "}, licencia = new OpenApilicense {name =" Apache 2.0 ", url = new Uri (" https: //www.apache.org/licenses/license-2.0.html ")}});
Consejo: use IntelliSense para ver qué otros campos están disponibles.
Con la configuración descrita anteriormente, el generador incluirá todas las operaciones de API en un solo documento de arrogancia. Sin embargo, puede crear múltiples documentos si es necesario. Por ejemplo, es posible que desee un documento separado para cada versión de su API. Para hacer esto, comience definiendo múltiples documentos de swagger en Startup.cs
:
Services.addsWaggerGen (c => {C.SwaggerDoc ("V1", new OpenApiInfo {title = "My API - V1", Version = "V1"}); C.SwaggerDoc ("V2", New OpenApiInfo {Title = " My API - V2 ", versión =" V2 "});})
Tome nota del primer argumento a SwaggerDoc. Debe ser un nombre amigable con URI que identifica de manera única el documento. Posteriormente se usa para inventar la ruta para solicitar el Swagger JSON correspondiente. Por ejemplo, con el enrutamiento predeterminado, los documentos anteriores estarán disponibles en "/swagger/v1/swagger.json" y "/swagger/v2/swagger.json".
A continuación, deberá informar a Swashbuckle qué acciones incluir en cada documento. Aunque esto se puede personalizar (ver más abajo), de forma predeterminada, el generador utilizará la propiedad ApiDescription.GroupName
, parte de la capa de metadatos incorporada que se envía con ASP.NET Core, para hacer esta distinción. Puede establecer esto decorando acciones individuales o aplicando una convención amplia de la aplicación.
Para incluir una acción en un documento de arrogancia específico, decórtela con ApiExplorerSettingsAttribute
y establezca GroupName
en el nombre del documento correspondiente (Case Sensitive):
[Httppost] [Apiexplorersettings (groupname = "v2")] public void post ([frombody] producto producto)
Para agrupar por convención en lugar de decorar cada acción, puede aplicar un controlador o convención de acción personalizado. Por ejemplo, puede conectar la siguiente convención para asignar acciones a documentos basados en el espacio de nombres del controlador.
// apiexplorerRugerPerverSionConvention.cspublic ApiexplorerRugerPerverSionConvention: icontrollermodelConvention {public void Aplication (ControlerModel Controller) {var controlerNamespace = controler.controllerType.namespace; // por ejemplo, "controladores.v1" var viversion = controlernamespace.split ('.'). Last (). TOLOWER (); Controller.apiexplorer.groupName = apiversion;}} // startup.cspublic void ConfigureServices (IserviceCollection Services) { Services.Addmvc (c => c.conventions.Add (new ApiExplorerGroupperVersionConvention ())); ...}
Al seleccionar acciones para un documento Swagger dado, el generador invoca un DocInclusionPredicate
con cada ApiDescription
que aparece en el marco. La implementación predeterminada inspecciona ApiDescription.GroupName
y devuelve verdadero si el valor es nulo o igual al nombre del documento solicitado. Sin embargo, también puede proporcionar un predicado de inclusión personalizado. Por ejemplo, si está utilizando un enfoque basado en atributos para implementar la versión API (por ejemplo, microsoft.aspnetcore.mvc.versioning), puede configurar un predicado personalizado que aprovecha los atributos de versiones en su lugar:
C.DocinClusionPredicate ((DocName, apidesc) => {if (! Apidesc.trygetMethodInfo (Out MethodInfo MethodInfo)) return False; var versions = MethodInfo.DeclaringType .getCustomATtributes (true) .OfType <PiversiTtribute) > attr.versions);
Si está utilizando el middleware SwaggerUI
, deberá especificar cualquier punto final de arrogancia adicional que desee exponer. Consulte la lista de múltiples documentos de arrogancia para más.
La especificación de arrogancia incluye un indicador deprecated
para indicar que una operación está en desuso y debe abstenerse de su uso. El generador Swagger establecerá automáticamente este indicador si la acción correspondiente está decorada con el ObsoleteAttribute
. Sin embargo, en lugar de configurar un indicador, puede configurar el generador para ignorar las acciones obsoletas por completo:
Services.addsWaggerGen (c => {... c.InignoreObSoleteActions ();};
También se puede utilizar un enfoque similar para omitir propiedades obsoletas de los esquemas en la salida de arrogancia. Es decir, puede decorar las propiedades del modelo con ObsoleteAttribute
y configurar Swashbuckle para omitir esas propiedades al generar esquemas JSON:
Services.addsWaggerGen (c => {... c.InignoreObSoleTeproperties ();};
Puede omitir las operaciones de la salida de swagger decorando acciones individuales o aplicando una convención amplia de la aplicación.
Para omitir una acción específica, decórtela con ApiExplorerSettingsAttribute
y establezca el indicador IgnoreApi
:
[Httpget ("{id}")] [apiexplorersettings (ignoreApi = true)] Producto público getByid (int id)
Para omitir las acciones por convención en lugar de decorarlas individualmente, puede aplicar una convención de acción personalizada. Por ejemplo, puede conectar la siguiente convención para documentar solo las operaciones de GET:
// apiexplorergetSonlyConvent.Cspublic class apiexplorergetSonlyConVention: iactionModelConvention {public void (ActionModel Action) {Action.apiexplorer.isVisible = Action.Attributes.ofType <httpGetTruteutic> (). Any ();}} // Servicios) {Services.Addmvc (c => C.Conventions.Add (new ApiexplorIrgetSonlyConvention ())); ...}
La especificación de Swagger permite que se asignen una o más "etiquetas" a una operación. El generador Swagger asignará el nombre del controlador como la etiqueta predeterminada. Es importante tener en cuenta si está utilizando el middleware SwaggerUI
, ya que utiliza este valor para las operaciones de grupo.
Puede anular la etiqueta predeterminada proporcionando una función que aplica etiquetas por convención. Por ejemplo, la siguiente configuración etiquetará y, por lo tanto, las operaciones de grupo en la interfaz de usuario, por método HTTP:
Services.addsWaggerGen (c => {... C.tagaccionsby (api => api.httpmethod);};
Por defecto, las acciones se ordenan mediante la etiqueta asignada (ver arriba) antes de que se agrupen en la estructura anidada centrada en la ruta de la especificación de arrogancia. Pero puede cambiar el orden de las acciones predeterminados con una estrategia de clasificación personalizada:
Services.addsWaggerGen (c => {... C.OrderActionsBy ((apidesc) => $ "{apidesc.actionDescriptor.RouteValues [" Controlador "]} _ {apidesc.httpmethod}");};
Nota: Esto dicta el orden de clasificación antes de que las acciones se agrupen y se transformen en el formato de arrogancia. Por lo tanto, afecta el orden de los grupos (es decir, "pathitems" de arrogancia) y el orden de operaciones dentro de un grupo, en la salida de arrogancia.
Si el generador encuentra un parámetro complejo o tipos de respuesta, generará un esquema JSON correspondiente, lo agregará al diccionario global components/schemas
y lo hará referencia a la descripción de la operación por ID única. Por ejemplo, si tiene una acción que devuelve un tipo Product
, el esquema generado se referenciará de la siguiente manera:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
Sin embargo, si encuentra múltiples tipos con el mismo nombre pero diferentes espacios de nombres (por ejemplo, RequestModels.Product
& ResponseModels.Product
), entonces Swashbuckle aumentará una excepción debido a "esquemas en conflicto". En este caso, deberá proporcionar una estrategia de identificación personalizada que califique aún más el nombre:
Services.addswaggerGen (c => {... c.customschemaids ((type) => type.fullName);};
Consulte #2703 para obtener apoyo para los tipos anidados.
Swashbuckle, Swashbuckle, hace un trabajo decente al generar esquemas JSON que describen con precisión su solicitud y respuesta de respuesta. Sin embargo, si está personalizando el comportamiento de serialización para ciertos tipos en su API, es posible que deba ayudarlo.
Por ejemplo, puede tener una clase con múltiples propiedades que desea representar en JSON como una cadena separada por comas. Para hacer esto, probablemente implementaría un JsonConverter
personalizado. En este caso, Swashbuckle no sabe cómo se implementa el convertidor y, por lo tanto, debe proporcionarle un esquema que describe con precisión el tipo:
// PhoneNumber.Cspublic Clase PhoneNumber {public String CountryCode {get; colocar; } Public String AreaCode {get; colocar; } Public String SubscriberId {get; colocar; }} // startup.csservices.addswaggergen (c => {... C.MapType <PhoneNumber> (() => New OpenApisChema {type = "String"});};
Swashbuckle expone una tubería de filtro que se conecta al proceso de generación. Una vez generados, los objetos de metadatos individuales se pasan a la tubería donde se pueden modificar más. Puede conectar filtros personalizados para enriquecer las "operaciones" generadas, "esquemas" y "documentos".
Swashbuckle recupera una ApiDescription
, parte de ASP.NET Core, para cada acción y la usa para generar una OpenApiOperation
correspondiente. Una vez generado, pasa la OpenApiOperation
y la ApiDescription
a través de la lista de filtros de operación configurados.
En una implementación de filtro típica, inspeccionaría la ApiDescription
para obtener información relevante (por ejemplo, información de ruta, atributos de acción, etc.) y luego actualizar la OpenApiOperation
en consecuencia. Por ejemplo, el siguiente filtro enumera una respuesta adicional de "401" para todas las acciones que están decoradas con el AuthorizeAttribute
:
// authResponseSoPerationFilter.Cspublic Class AuthESSponseSeSoperationFilter: iOperationFilter {public void Aplication (OpenApioPeration Operation, OperationFilterContext context) {var authattributes (context.methodinfo.declaringType.getCustomattributes (verdadero) .Union (context.methodinfo. <AutorizeTtribute > (); if (authattributes.any ()) operation.responses.add ("401", new OpenApiresponse {descripción = "no autorizado"});}} // startup.csservices.addswaggergen (c => {... ... c.operationFilter <authResponseSePerationFilter> ();};
Nota: Las tuberías de filtro son DI ADACE. Es decir, puede crear filtros con parámetros del constructor y si los tipos de parámetros están registrados con el marco DI, se inyectarán automáticamente cuando los filtros estén instanciados
Swashbuckle genera un Jsonschema con sabor a arrogancia para cada parámetro, respuesta y tipo de propiedad expuesto por las acciones de su controlador. Una vez generado, pasa el esquema y escribe a través de la lista de filtros de esquema configurados.
El siguiente ejemplo agrega una extensión de proveedor automático (ver https://github.com/azure/autorest/blob/master/docs/extensions/readme.md#x-ms-enum) para informar la herramienta Autorest cómo se deben modelar enumss Cuando genera el cliente API.
// AutoRestSchemaFilter.cspublic class AutoRestSchemaFilter : ISchemaFilter{public void Apply(OpenApiSchema schema, SchemaFilterContext context){var type = context.Type;if (type.IsEnum){schema.Extensions.Add("x-ms-enum",new OpenapioBject {["name"] = new OpenApistring (type.name), ["modelAsString"] = new OpenApiBoLean (true)});};}} // startup.csservices.addswaggerGen (c => {c ... c .Schemafilter <autorestschemafilter> ();};
El siguiente ejemplo permite la generación automática de esquemas de objetos de Dictionary<Enum, TValue>
. Tenga en cuenta que esto solo genera la arrogancia; System.Text.Json
no puede analizar en las enums del diccionario de forma predeterminada, por lo que necesitará un JSONConverter especial, como en .NET Docs.
// DictionaryTKeyenumtValueschemafilter.cspublic DictionaryTKeyenumtValueschemafilter: ischemafilter { Public void Aplication (OpenApisChema Schema, SchemafilterContext Context) {// Solo se ejecuta para campos que son un diccionario <enum, tvalue> if (! Context.type.isGenericType || var keyType = context.type.getGenericArGuments () [0]; var valueType = context.type.getGenericAns = keyType.getenumnames (). TODICCIONARY (name => name, name => context.schemagenerator.generateschema (valueType, context.schemarepository)); }} // startup.csservices.addswaggergen (c => {... // Estos serán reemplazados por diccionarytkeyenumtValueschemafilter, pero son necesarios para evitar un error.// necesitará uno para cada tipo de diccionario <,> que tiene .C.MapType <Dictionary <MyEnum, List <String>>> (() => new OpenApisChema ()); C.Schemafilter <DictionAyTKeyEnumtValuesChemaFilter> ();};
Una vez que se ha generado un OpenApiDocument
, también se puede pasar a través de un conjunto de filtros de documentos preconfigurados. Esto proporciona el control total para modificar el documento, sin embargo, se le vea ajuste. Para asegurarse de que todavía está devolviendo Swagger JSON válido, debe leer la especificación antes de usar este tipo de filtro.
El siguiente ejemplo proporciona una descripción para cualquier etiqueta asignada a las operaciones en el documento:
public class tagDescriptionsDocumentFilter: IdocumentFilter {public void Aplication (OpenApidocument SwaggerDoc, DocumentFilterContext context) {swaggerDoc.Tags = nueva lista <enenpitapitag> {new OpenApitag {name = "Products", Descripción = "Explorar/Administrar el Catalog del Producto"}, Nuevo {Name = "Orders", Descripción = "Enviar órdenes"}};}}
Nota: Si está utilizando el middleware SwaggerUI
, el TagDescriptionsDocumentFilter
demostrado anteriormente podría usarse para mostrar descripciones adicionales junto a cada grupo de operaciones.
En Swagger, puede describir cómo se asegura su API definiendo uno o más esquemas de seguridad (por ejemplo, básico, clave API, OAuth2, etc.) y declarando cuáles de esos esquemas son aplicables a nivel mundial o para operaciones específicas. Para obtener más detalles, eche un vistazo al objeto de requisito de seguridad en la especificación Swagger.
En Swashbuckle, puede definir esquemas invocando el método AddSecurityDefinition
, proporcionando un nombre y una instancia de OpenApiSecurityScheme
. Por ejemplo, puede definir una OAuth 2.0 - Flujo implícito de la siguiente manera:
// startup.csservices.addswaggergen (c => {... // Defina el esquema OAuth2.0 que está en uso (es decir, flujo implícito) C.addSecurityDefinition ("Oauth2", New OpenApiseSecurityScheme {type = SecuritySchemetype.oauth2, flujos = new OpenApioAuthFlows {implicT = new OpenApioAuthflow {AuthorizationUrl = new Uri ("/auth-server/Connect/autorize", urikind.relative), Scopes = new Dictionary <String, String> {{"Readaccess", "Access Read Operations"} , {"WriteAccess", "Access Write Operations"}}}}});};
Nota: Además de definir un esquema, también debe indicar a qué operaciones es aplicable ese esquema. Puede aplicar esquemas a nivel mundial (es decir, todas las operaciones) a través del método AddSecurityRequirement
. El siguiente ejemplo indica que el esquema llamado "OAuth2" debe aplicarse a todas las operaciones, y que se requieren los ámbitos "Readaccess" y "WriteAccess". Al aplicar esquemas de tipo que no sean "OAuth2", la matriz de ámbitos debe estar vacía.
c.AddSwaggerGen(c =>{ ... c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } }, new[] { "readAccess", " WriteAccess "}}});})
Si tiene esquemas que solo son aplicables para ciertas operaciones, puede aplicarlos a través de un filtro de operación. Por ejemplo, el siguiente filtro agrega requisitos de OAUTH2 basados en la presencia del AuthorizeAttribute
:
// SecurityRequirementsOperationFilter.cspublic SecurityRequirementsOperationFilter: IoperationFilter {public void Aplication (OpenApioPeration Operation, OperationFilterContext context) {// Policy Names Map a ScopesVar RequiredScopes = context.methodinfo.getCustomattributes (verdadero). > attr.policy) .distinct (); if (requiredScopes.any ()) {Operation.ResponseSes.Add ("401", nuevo OpenApiresponse {Descripción = "no autorizado"}); Operation.Responses.Add ("403", new OpenApireSponse {Descripción = "Forbidden"}); var oauthscheme = new OpenApiseCurityScheme {reference = new OpenApireference {type = referenceType.SecurityScheme, id = "oauth2"}}; operation.security = new ListapiseCureSeRityRequirement> {newPreapisEcurity oauthscheme] = requiredScopes.tolist ()}};}}}
Nota: Si está utilizando el middleware SwaggerUI
, puede habilitar flujos interactivos de OAuth2.0 que funcionan con metadatos de seguridad emitidos. Consulte habilitar los flujos OAuth2.0 para obtener más detalles.
Services.addsWaggerGen (c => {C.addsecuityDefinition ("bearerauth", new OpenApiseCurityScheme {type = SecuritySchemeType.http, esquema = "bearer", bearFormat = "JWT", Descripción = "JWT Autorization Header utilizando el Scheme". "}} );
Swagger / Openapi define las allOf
y oneOf
las palabras clave para describir las relaciones de herencia y polimorfismo en las definiciones de esquemas. Por ejemplo, si está utilizando una clase base para modelos que comparten propiedades comunes, puede usar la palabra clave allOf
para describir la jerarquía de herencia. O, si su serializador admite la serialización/deserialización polimórficas, puede usar la palabra clave oneOf
para documentar todos los esquemas "posibles" para las solicitudes/respuestas que varían según el subtipo.
Por defecto, Swashbuckle aplana las jerarquías de herencia. Es decir, para los modelos derivados, las propiedades heredadas se combinan y enumeran junto con las propiedades declaradas. Esto puede causar mucha duplicación en la arrogancia generada, particularmente cuando hay múltiples subtipos. También es problemático si está utilizando un generador de clientes (por ejemplo, NSWAG) y desea mantener la jerarquía de herencia en los modelos de clientes generados. Para trabajar en torno a esto, puede aplicar la configuración de UseAllOfForInheritance
, y esto aprovechará la palabra clave allOf
para incorporar propiedades hereditarias por referencia en la arrogancia generada:
Circle: { type: "object", allOf: [ { $ref: "#/components/schemas/Shape" } ], properties: { radius: { type: "integer", format: "int32", } }, }, Shape: { type: "object", properties: { name: { type: "string", nullable: true, } }, }
Si su serializador admite la serialización/deserialización polimórfica y desea enumerar los posibles subtipos para una acción que acepte/devuelva los tipos de base abstractos, puede aplicar la configuración de UseOneOfForPolymorphism
. Como resultado, los esquemas de solicitud/respuesta generados harán referencia a una colección de esquemas "posibles" en lugar de solo el esquema de clase base:
requestBody: { content: { application/json: { schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], } } }
Como las relaciones de herencia y polimorfismo a menudo pueden volverse bastante complejas, no solo en sus propios modelos, sino también dentro de la biblioteca de clases .NET, Swashbuckle es selectivo sobre qué jerarquías se expone y no expone en la arrogancia generada. Por defecto, recogerá los subtipos que se definan en el mismo ensamblaje que un tipo de base dado. Si desea anular este comportamiento, puede proporcionar una función selectora personalizada:
Services.addswaggerGen (c => {... c.useallofforinheritance (); c.selectsubTypeSusing (basetype => {return typeOf (startup) .assembly.gettypes (). Where (type => type.issubClassof (basetype)); })});
Nota: Si está utilizando la biblioteca de anotaciones Swashbuckle, contiene un selector personalizado basado en la presencia de atributos SwaggerSubType
en las definiciones de clase base. De esta manera, puede usar atributos simples para enumerar explícitamente las relaciones de herencia y/o polimorfismo que desea exponer. Para habilitar este comportamiento, consulte los documentos de anotaciones.
Junto con las palabras oneOf
y / o allOf
las palabras clave, Swagger / OpenAPI admite un campo discriminator
en las definiciones de esquema base. Esta palabra clave apunta a la propiedad que identifica el tipo específico representado por una carga útil dada. Además del nombre de la propiedad, la descripción de Discriminator también puede incluir una mapping
que mapea los valores del discriminador a definiciones de esquema específicas.
Por ejemplo, el Serializer Newtonsoft admite la serialización/deserialización polimórficas emitiendo/aceptando una propiedad "$ tipo" en las instancias JSON. El valor de esta propiedad será el nombre de tipo calificado de ensamblaje del tipo representado por una instancia JSON dada. Entonces, para describir explícitamente este comportamiento en Swagger, el esquema de solicitud/respuesta correspondiente podría definirse de la siguiente manera:
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" } ], ... } } }
Si UseAllOfForInheritance
o UseOneOfForPolymorphism
está habilitado, y su serializador admite (y ha habilitado) emitir/aceptar una propiedad discriminadora, entonces SwashBuckle generará automáticamente los metadatos discriminator
correspondientes en las definiciones de esquemas base.
Alternativamente, si ha personalizado su serializador para admitir la serialización/deserialización polimórficas, puede proporcionar algunas funciones selectivas personalizadas para determinar el nombre del discriminador y la asignación correspondiente:
Services.addswaggerGen (c => {... c.useOneOfforInHeritance (); C.SelectDISCriminatornameUsing ((Basetype) => "Typename"); C.SelectDiscriminatorValueUsing ((Subtype) => Subtype.name);});
Nota: Si está utilizando la biblioteca de anotaciones Swashbuckle, contiene funciones selectores personalizadas que se basan en la presencia de atributos SwaggerDiscriminator
y SwaggerSubType
en las definiciones de clase base. De esta manera, puede usar atributos simples para proporcionar metadatos discriminadores explícitamente. Para habilitar este comportamiento, consulte los documentos de anotaciones.
Por defecto, la interfaz de usuario de Swagger estará expuesta en "/Swagger". Si es necesario, puede alterar esto al habilitar el middleware Swaggerui:
App.UseSWaggerUi (c => {c.RoutePrefix = "API-DOCS"}
Por defecto, la interfaz de usuario de Swagger tendrá un título de documento genérico. Cuando tienes varias páginas de arrogancia abiertas, puede ser difícil distinguirlas. Puede alterar esto al habilitar el middleware Swaggerui:
App.UseSwaggerui (c => {C.DocumentTitle = "My Swagger UI";}
Por defecto, la interfaz de usuario de Swagger incluye CSS y JS predeterminados, pero si desea cambiar la ruta o la URL (por ejemplo, para usar un CDN):
App.UseSwaggerui (c => {c.stylespath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui.min.css"; c.scriptbundlepath = "https : //cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui-bundle.min.js "; c.scriptpresetspath =" https://cdnjs.cloudflare.com/ajax/libs /swagger-ui/5.17.10/swagger-ui-standalone-preset.min.js ";}
Al habilitar el middleware, debe especificar uno o más puntos finales Swagger (totalmente calificados o relativos a la página de la interfaz de usuario) para alimentar la interfaz de usuario. Si proporciona múltiples puntos finales, se enumerarán en la esquina superior derecha de la página, lo que permite a los usuarios alternar entre los diferentes documentos. Por ejemplo, la siguiente configuración podría usarse para documentar diferentes versiones de una API.
App.UseSwaggerui (c => {C.SwaggerEndpoint ("/Swagger/V1/Swagger.json", "V1 Docs"); C.SwaggerendPoint ("/Swagger/V2/Swagger.json", "V2 Docs"); }
El Swagger-UI se envía con su propio conjunto de parámetros de configuración, todos descritos aquí. En Swashbuckle, la mayoría de estos aparecen a través de las opciones de middleware de Swaggerui:
App.UseSWaggerUi (c => {C.DefaultModelExPanddepth (2); C.DefaultModelRendering (ModelRendering.Model); C.DefaultModelsexpandDepth (-1); C.DisplaYoperationId (); C.DisplayRequestduration (); C.Docexpansion (doCeCeCe. Ninguno) ["MyCustomplugin"]; ) => {Respuesta de retorno;} ");});
Nota
Al agregar complementos personalizados, asegúrese de agregar cualquier archivo js
personalizado que defina las funciones del complemento.
Para ajustar el comportamiento, puede inyectar archivos JavaScript adicionales agregándolos a su carpeta wwwroot
y especificando las rutas relativas en las opciones de middleware:
App.UseSWaggerUi (c => {C.InjectJavaScript ("/Swagger-ui/Custom.js");}
Nota: Las opciones InjectOnCompleteJavaScript
y InjectOnFailureJavaScript
se han eliminado porque la última versión de Swagger-UI no expone los ganchos necesarios. En cambio, proporciona un sistema de personalización flexible basado en conceptos y patrones de React y Redux. Para aprovechar esto, deberá proporcionar una versión personalizada de index.html como se describe a continuación.
La aplicación de muestra de índice personalizado demuestra este enfoque, utilizando el sistema de complementos Swagger-UI que proporciona una barra superior personalizada y oculta el componente de información.
Para ajustar el aspecto y la sensación, puede inyectar hojas de estilo CSS adicionales agregándolas a su carpeta wwwroot
y especificando las rutas relativas en las opciones de middleware:
App.UseSWaggerUi (c => {C.InjectStylesheet ("/Swagger-ui/Custom.css");}
Para personalizar la interfaz de usuario más allá de las opciones básicas enumeradas anteriormente, puede proporcionar su propia versión de la página Swagger-UI index.html:
App.UseSWaggerUi (c => {C.IndexStream = () => getType (). Assembly .getManifestreseurCestream ("Customuiindex.swagger.index.html"); // requiere que el archivo se agregue como un recurso incrustado});
Para comenzar, debe basar su índice personalizado.html en la versión predeterminada
El Swagger-UI tiene apoyo incorporado para participar en los flujos de autorización de OAuth2.0. Interactúa con la autorización y/o puntos finales de tokens, como se especifica en el Swagger JSON, para obtener tokens de acceso para las llamadas de API posteriores. Consulte Agregar definiciones y requisitos de seguridad para un ejemplo de agregar metadatos OAuth2.0 al arrogancia generado.
Si su punto final Swagger incluye los metadatos de seguridad apropiados, la interacción de la interfaz de usuario debe habilitarse automáticamente. Sin embargo, puede personalizar aún más el soporte OAuth en la interfaz de usuario con la siguiente configuración a continuación. Vea la documentación de Swagger-UI para obtener más información:
App.UseSWaggerui (c => {c.oauthclientid ("test-id"); c.oauthclientsecret ("test-secret"); c.oauthusername ("test-user"); c.oautrealm ("test-realm" ); String, String> {{"foo", "bar"}});
Para usar interceptores personalizados en las solicitudes y respuestas que pasan por Swagger-UI, puede definirlos como funciones de JavaScript en la configuración:
App.UseSWaggerUi (c => {c.useRequestInterceptor ("(req) => {req.headers ['x-my-custom-header'] = 'mycustomValue'; return req;}"); c.useresponseinterceptor (" (res) => {console.log ('Respuesta interceptada de interceptor personalizado de:', res.url);
Esto puede ser útil en una variedad de escenarios en los que es posible que desee agregar tokens XSRF locales a todas las solicitudes, por ejemplo:
App.UseSWaggerUi (c => {c.useRequestInterceptor ("(req) => {req.headers ['x-xsrf-token'] = localstorage.getitem ('xsrf-token'); return req;}"); });
Instale el siguiente paquete Nuget en su aplicación ASP.NET Core.
Package Manager : Install-Package Swashbuckle.AspNetCore.Annotations CLI : dotnet add package Swashbuckle.AspNetCore.Annotations
En el método ConfigureServices
de Startup.cs
, habilite anotaciones dentro del bloque de configuración Swagger:
Services.addsWaggerGen (c => {... C.enableanNotations ();});
Una vez que se habilitan las anotaciones, puede enriquecer los metadatos de operación generados decorando las acciones con un SwaggerOperationAttribute
.
[Httppost] [swaggerperation (summary = "crea un nuevo producto", descripción = "requiere privilegios de administrador", operationId = "createProduct", tags = new [] {"compra", "productos"})] public IcactionResult create ([[ Frombody] producto producto)
ASP.NET Core proporciona el ProducesResponseTypeAttribute
para enumerar las diferentes respuestas que una acción puede devolver. Estos atributos se pueden combinar con comentarios XML, como se describió anteriormente, para incluir descripciones amigables para los humanos con cada respuesta en la arrogancia generada. Si prefiere hacer todo esto con un solo atributo, y evite el uso de comentarios XML, puede usar SwaggerResponseAttribute
s en su lugar:
[Httppost] [swaggerResponse (201, "el producto fue creado", typeof (producto))] [swaggerResponse (400, "los datos del producto no son válidos")] Public iActionResult Create ([fromBody] Product Product Product)
Puede anotar los parámetros o propiedades vinculadas "consulta" o "encabezado" (es decir, decorado con [FromRoute]
, [FromQuery]
o [FromHeader]
) con un SwaggerParameterAttribute
para enriquecer los metadatos Parameter
correspondientes generados por swashbuckle:
[Httpget] public iActionResult getProducts ([fromQuery, swaggerParameter ("Palabras clave de búsqueda", requirir = true)] Palabras clave de cadena)
Puede anotar parámetros o propiedades vinculados al "cuerpo" (es decir, decorado con [FromBody]
) con un SwaggerRequestBodyAttribute
para enriquecer los metadatos RequestBody
correspondientes generados por swashbuckle:
[Httppost] Public iActionResult CreateProduct ([fromBody, SwaggerRequestBody ("La carga útil del producto", requerido = verdadero)] Producto del producto)
Puede anotar clases o propiedades con un SwaggerSchemaAttribute
para enriquecer los metadatos Schema
correspondientes generados por SwashBuckle:
[SwaggersChema (requerido = nuevo [] {"Descripción"})] Producto de clase pública {[SwaggersChema ("El identificador del producto", readonly = true)] public int id {get; colocar; } [SwaggersChema ("La descripción del producto")] Public String Descripción {get; colocar; } [SwaggersChema ("La fecha en que se creó", format = "fecha")] public dateTime Datecreated {get; colocar; }}
Nota: En Swagger / Openapi, los objetos serializados y las propiedades contenidas se representan como instancias Schema
, de ahí que esta anotación se pueda aplicar tanto a clases como a propiedades. También vale la pena señalar que las propiedades "requeridas" se especifican como una variedad de nombres de propiedades en el esquema de nivel superior en lugar de una bandera en cada propiedad individual.
El paquete SwaggerGen
proporciona varios puntos de extensión, incluidos los filtros de esquema (descritos aquí) para personalizar todos los esquemas generados. Sin embargo, puede haber casos en los que sea preferible aplicar un filtro a un esquema específico. Por ejemplo, si desea incluir un ejemplo para un tipo específico en su API. Esto se puede hacer decorando el tipo con un SwaggerSchemaFilterAttribute
:
// Product.cs [SwaggersChemaFilter (typeoF (ProductSchEmafilter))] Public Class Product {...} // ProductSchEmafilter.Cspublic Class ProductsChemafilter: ischemafilter {public void Aplication (OpenApisChema Schema, SchemAfilterContext context) {Schema.Explay = NewApiObiAns ["Id"] = new OpenApiinteger (1), ["Descripción"] = New OpenApistring ("Un producto increíble")};}}
Por defecto, el generador Swagger etiquetará todas las operaciones con el nombre del controlador. Esta etiqueta se usa para impulsar las agrupaciones de operaciones en Swagger-UI. Si desea proporcionar una descripción para cada uno de estos grupos, puede hacerlo agregando metadatos para cada etiqueta de nombre del controlador a través del SwaggerTagAttribute
:
[Swaggertag ("Crear, leer, actualizar y eliminar productos")] Public Class ProductsController {...}
Nota: Esto agregará la descripción anterior específicamente a la etiqueta llamada "Productos". Por lo tanto, debe evitar usar este atributo si está etiquetando operaciones con algo más que el nombre del controlador, por ejemplo, si está personalizando el comportamiento de etiquetado con TagActionsBy
.
Si desea usar la herencia de Swashbuckle y/o el comportamiento del polimorfismo, puede usar anotaciones para indicar explícitamente los subtipos "conocidos" para un tipo de base dado. Esto anulará la función selectora predeterminada, que selecciona todos los subtipos en el mismo ensamblaje que el tipo base y, por lo tanto, debe habilitarse explícitamente cuando habilita anotaciones:
// startup.csservices.addswaggergen (c => {c.enableannotations (EnlanNoTationsForInheritance: true, EnlanseNotationsForPolyMorphism: true);}); // shape.cs [swaggerSubtype (typeOf (rectangle)) [swaggersubtype (typeOf (circle))) ] Forma de clase abstracta pública {}
Si está utilizando anotaciones para indicar explícitamente los subtipos "conocidos" para un tipo de base polimórfica, puede combinar el SwaggerDiscriminatorAttribute
con el SwaggerSubTypeAttribute
para proporcionar metadatos adicionales sobre la propiedad "Discriminador", que luego se incorporará a la definición de esquemas generados:
// startup.csservices.addswaggergen (c => {c.enableannotations (enleSeanNotationsForInheritance: true, EnlineNotationsForPolyMorphism: true);}); // sape.cs [swaggerDisCriminator ("shapetype") = "rectángulo")] [swaggersubtype (typeof (circle), discriminatorValue = "círculo")] forma de clase abstracta public {public shapeType {get; colocar; }}
Esto indica que la carga útil correspondiente tendrá una propiedad "ShapeType" para discriminar entre los subtipos, y esa propiedad tendrá un valor de "rectángulo" si la carga útil representa un tipo Rectangle
y un valor de "círculo" si representa un tipo Circle
. Este detalle se describirá en la definición de esquema generada de la siguiente manera:
schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], discriminator: { propertyName: shapeType, mapping: { rectangle: "#/components/schemas/Rectangle", circle: "#/components/schemas/Circle", } } }
Una vez que su aplicación se haya configurado con SwashBuckle (ver comenzando), puede usar la herramienta Swashbuckle CLI para recuperar Swagger / OpenApi JSON directamente del ensamblaje de inicio de su aplicación, y escribirla en el archivo. Esto puede ser útil si desea incorporar la generación Swagger en un proceso CI/CD, o si desea servirlo desde el archivo estático en el tiempo de ejecución.
Está empaquetado como una herramienta .NET que se puede instalar y usar a través del SDK de Dotnet.
️ La herramienta debe cargar su DLL de inicio y sus dependencias en tiempo de ejecución. Por lo tanto, debe usar una versión deldotnet
SDK que sea compatible con su aplicación. Por ejemplo, si su aplicación se dirige anet6.0
, entonces debe usar la versión 6.0.xxx del SDK para ejecutar la herramienta CLI. Si se dirige anet8.0
, entonces debe usar la versión 8.0.xxx del SDK y así sucesivamente.
Instalar como una herramienta global
dotnet tool install -g Swashbuckle.AspNetCore.Cli
Verifique que la herramienta se instalara correctamente
swagger tofile --help
Genere un documento Swagger/ OpenAPI desde el ensamblaje de inicio de su aplicación
swagger tofile --output [output] [startupassembly] [swaggerdoc]
Dónde ...
[salida] es la ruta relativa donde se emitirá el swagger json a
[startupAssembly] es la ruta relativa al ensamblaje de inicio de su aplicación
[SwaggerDoc] es el nombre del documento Swagger que desea recuperar, tal como está configurado en su clase de inicio
En la raíz de su proyecto, cree un archivo manifiesto de herramienta:
dotnet new tool-manifest
Instalar como herramienta local
dotnet tool install Swashbuckle.AspNetCore.Cli
Verifique que la herramienta se instalara correctamente
dotnet swagger tofile --help
Genere un documento Swagger / OpenAPI desde el ensamblaje de inicio de su aplicación
dotnet swagger tofile --output [output] [startupassembly] [swaggerdoc]
Dónde ...
[salida] es la ruta relativa donde se emitirá el swagger json a
[startupAssembly] es la ruta relativa al ensamblaje de inicio de su aplicación
[SwaggerDoc] es el nombre del documento Swagger que desea recuperar, tal como está configurado en su clase de inicio
Ups-in-the-box, la herramienta se ejecutará en el contexto de un host web "predeterminado". Sin embargo, en algunos casos, es posible que desee traer su propio entorno de host, por ejemplo, si ha configurado un contenedor DI personalizado como AutoFAC. Para este escenario, la herramienta Swashbuckle CLI expone un gancho basado en convenciones para su aplicación.
Es decir, si su aplicación contiene una clase que cumple con cualquiera de las siguientes convenciones de nombres, entonces esa clase se utilizará para proporcionar un host para que la herramienta CLI se ejecute.
public class SwaggerHostFactory
, que contiene un método estático público llamado CreateHost
con retorno tipo IHost
public class SwaggerWebHostFactory
, que contiene un método estático público llamado CreateWebHost
con return Type IWebHost
Por ejemplo, la siguiente clase podría usarse para aprovechar la misma configuración del host que su aplicación:
public class swaggerHostFactory {public static ihost createHost () {return programa.createhostBuilder (nueva cadena [0]). Build ();}}
Por defecto, la interfaz de usuario redoc se expuso en "/API-DOC". Si es necesario, puede alterar esto al habilitar el middleware redoc:
App.UsebedoC (c => {C.RoutePrefix = "Docs" ...}
Por defecto, la interfaz de usuario de Redoc tendrá un título de documento genérico. Puede alterar esto al habilitar el middleware redoc:
App.UsebedoC (c => {C.DocumentTitle = "My API Docs"; ...}
Redoc se envía con su propio conjunto de parámetros de configuración, todos descritos aquí https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object. En Swashbuckle, la mayoría de estos aparecen a través de las opciones de middleware redoc:
app.UsebRoReC (c => {c.specurl ("/v1/swagger.json"); c.enableUntrustedSpec (); c.scrolllyOffset (10); c.hidehostName (); c.hidioDownloadButton (); c.Expandrossesses ("200,201"; Sortpropsalphabeticalmente ();});
Usar c.SpecUrl("/v1/swagger.json")
varias veces dentro de los mismos UseReDoc(...)
no agregará múltiples URL.
Para ajustar el aspecto y la sensación, puede inyectar hojas de estilo CSS adicionales agregándolas a su carpeta wwwroot
y especificando las rutas relativas en las opciones de middleware:
App.UsebedoC (c => {... C.InjectStylesheet ("/redoc/custom.css");}
También es posible modificar el tema utilizando la propiedad AdditionalItems
, consulte https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object para obtener más información.
App.UsebedoC (c => {... C.ConfigObject.AdditionalItems = ...}
Para personalizar la interfaz de usuario más allá de las opciones básicas enumeradas anteriormente, puede proporcionar su propia versión de la página redoc index.html:
App.UsebedoC (c => {C.IndexStream = () => getType (). Assembly .getManifestressourCestream ("customIndex.redoc.index.html"); // requiere que el archivo se agregue como un recurso integrado});
Para comenzar, debe basar su índice personalizado.html en la versión predeterminada