Saltar al pie de página
.NET AYUDA

Swashbuckle ASP .NET Core (Cómo funciona para desarrolladores)

Swashbuckle es un paquete de NuGet para C# .NET Core NuGet que ayuda a documentar automáticamente APIs Web RESTful. En este blog, vamos a explorar los paquetes NuGet de Swashbuckle ASP.NET Core y IronPDF Installation Instructions, permitiendo el desarrollo moderno de APIs web en ASP.NET Core. Juntos, proporcionan una serie de funcionalidades que se pueden lograr con un código mínimo.

Las páginas de documentación de la API se muestran utilizando la herramienta Swagger UI, que utiliza un archivo swagger.json generado a partir del proyecto de la API web. El documento JSON generado sigue el estándar Open API. Swashbuckle está disponible como un paquete de NuGet Swashbuckle.AspNetCore, que al instalarlo y configurarlo expondrá automáticamente el JSON de Swagger. La herramienta Swagger UI lee el archivo JSON de Swagger, generado a partir de comentarios XML escritos en las APIs. Además, se puede crear un archivo de documentación XML habilitándolo en el archivo de configuración del proyecto. Los comentarios XML se convierten en un archivo de documentación XML, a partir del cual se genera el JSON de Swagger. Luego, el middleware Swagger lee el JSON y expone los endpoints JSON de Swagger.

Implementación en un proyecto de API web .NET Core

Comencemos con un proyecto de API web:

dotnet new webapi -n SwashbuckleDemo
cd SwashbuckleDemo
dotnet build
dotnet add package Swashbuckle.AspNetCore --version 6.5.0
dotnet build
dotnet new webapi -n SwashbuckleDemo
cd SwashbuckleDemo
dotnet build
dotnet add package Swashbuckle.AspNetCore --version 6.5.0
dotnet build
SHELL

Aquí, creamos un proyecto de API web llamado "SwashbuckleDemo" y luego instalamos el paquete Swashbuckle en el proyecto API web de .NET Core usando la consola del administrador de paquetes.

Configurar Swagger Middleware

Configurar servicios de Swagger en el archivo Startup.cs.

using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Other service configurations...

        // Register the Swagger generator
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });

            // Optionally, include XML comments for additional information
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Other app configurations...

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable Swagger UI (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }
}
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Other service configurations...

        // Register the Swagger generator
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });

            // Optionally, include XML comments for additional information
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Other app configurations...

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable Swagger UI (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }
}
Imports System.Reflection
Imports Microsoft.Extensions.DependencyInjection
Imports Microsoft.AspNetCore.Builder

Public Class Startup
	Public Sub ConfigureServices(ByVal services As IServiceCollection)
		' Other service configurations...

		' Register the Swagger generator
		services.AddSwaggerGen(Sub(c)
			c.SwaggerDoc("v1", New OpenApiInfo With {
				.Title = "My API",
				.Version = "v1"
			})

			' Optionally, include XML comments for additional information
			Dim xmlFile = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"
			Dim xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile)
			c.IncludeXmlComments(xmlPath)
		End Sub)
	End Sub

	Public Sub Configure(ByVal app As IApplicationBuilder, ByVal env As IHostingEnvironment)
		' Other app configurations...

		' Enable middleware to serve generated Swagger as a JSON endpoint.
		app.UseSwagger()

		' Enable Swagger UI (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
		app.UseSwaggerUI(Sub(c)
			c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")
		End Sub)
	End Sub
End Class
$vbLabelText   $csharpLabel

Agregar un controlador para APIs de lista de tareas:

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

// Example to define an entity class
public class Todo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
}

// Example to define a DbContext class
public class TodoDb : DbContext
{
    public DbSet<Todo> Todos => Set<Todo>();
}

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "SwashbuckleDemo!");

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync());

app.MapGet("/todoitems/complete", async (TodoDb db) =>
    await db.Todos.Where(t => t.IsComplete).ToListAsync());

app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
    await db.Todos.FindAsync(id) is Todo todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.MapPost("/todoitems", async (Todo todo, TodoDb db) =>
{
    db.Todos.Add(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todoitems/{todo.Id}", todo);
});

app.MapPut("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) =>
{
    var todo = await db.Todos.FindAsync(id);
    if (todo is null) return Results.NotFound();
    todo.Name = inputTodo.Name;
    todo.IsComplete = inputTodo.IsComplete;
    await db.SaveChangesAsync();
    return Results.NoContent();
});

app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) =>
{
    if (await db.Todos.FindAsync(id) is Todo todo)
    {
        db.Todos.Remove(todo);
        await db.SaveChangesAsync();
        return Results.Ok(todo);
    }

    return Results.NotFound();
});

app.Run();
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

// Example to define an entity class
public class Todo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsComplete { get; set; }
}

// Example to define a DbContext class
public class TodoDb : DbContext
{
    public DbSet<Todo> Todos => Set<Todo>();
}

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "SwashbuckleDemo!");

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync());

app.MapGet("/todoitems/complete", async (TodoDb db) =>
    await db.Todos.Where(t => t.IsComplete).ToListAsync());

app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
    await db.Todos.FindAsync(id) is Todo todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.MapPost("/todoitems", async (Todo todo, TodoDb db) =>
{
    db.Todos.Add(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todoitems/{todo.Id}", todo);
});

app.MapPut("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) =>
{
    var todo = await db.Todos.FindAsync(id);
    if (todo is null) return Results.NotFound();
    todo.Name = inputTodo.Name;
    todo.IsComplete = inputTodo.IsComplete;
    await db.SaveChangesAsync();
    return Results.NoContent();
});

app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) =>
{
    if (await db.Todos.FindAsync(id) is Todo todo)
    {
        db.Todos.Remove(todo);
        await db.SaveChangesAsync();
        return Results.Ok(todo);
    }

    return Results.NotFound();
});

app.Run();
Imports Microsoft.AspNetCore.Http.HttpResults
Imports Microsoft.AspNetCore.Builder
Imports Microsoft.EntityFrameworkCore
Imports Microsoft.AspNetCore.Mvc
Imports System.Threading.Tasks

' Example to define an entity class
Public Class Todo
	Public Property Id() As Integer
	Public Property Name() As String
	Public Property IsComplete() As Boolean
End Class

' Example to define a DbContext class
Public Class TodoDb
	Inherits DbContext

	Public ReadOnly Property Todos() As DbSet(Of Todo)
		Get
			Return [Set](Of Todo)()
		End Get
	End Property
End Class

Private builder = WebApplication.CreateBuilder(args)
Private app = builder.Build()

app.MapGet("/", Function() "SwashbuckleDemo!")

app.MapGet("/todoitems", Async Function(db As TodoDb) Await db.Todos.ToListAsync())

app.MapGet("/todoitems/complete", Async Function(db As TodoDb) Await db.Todos.Where(Function(t) t.IsComplete).ToListAsync())

Dim tempVar As Boolean = TypeOf db.Todos.FindAsync(id) Is Todo
Dim todo As Todo = If(tempVar, CType(db.Todos.FindAsync(id), Todo), Nothing)
app.MapGet("/todoitems/{id}", Async Function(id As Integer, db As TodoDb)If(Await tempVar, Results.Ok(todo), Results.NotFound()))

app.MapPost("/todoitems", Async Function(todo As Todo, db As TodoDb)
	db.Todos.Add(todo)
	Await db.SaveChangesAsync()
	Return Results.Created($"/todoitems/{todo.Id}", todo)
End Function)

app.MapPut("/todoitems/{id}", Async Function(id As Integer, inputTodo As Todo, db As TodoDb)
	Dim todo = Await db.Todos.FindAsync(id)
	If todo Is Nothing Then
		Return Results.NotFound()
	End If
	todo.Name = inputTodo.Name
	todo.IsComplete = inputTodo.IsComplete
	Await db.SaveChangesAsync()
	Return Results.NoContent()
End Function)

app.MapDelete("/todoitems/{id}", Async Function(id As Integer, db As TodoDb)
	Dim tempVar2 As Boolean = TypeOf db.Todos.FindAsync(id) Is Todo
	Dim todo As Todo = If(tempVar2, CType(db.Todos.FindAsync(id), Todo), Nothing)
	If Await tempVar2 Then
		db.Todos.Remove(todo)
		Await db.SaveChangesAsync()
		Return Results.Ok(todo)
	End If

	Return Results.NotFound()
End Function)

app.Run()
$vbLabelText   $csharpLabel

Un controlador se puede agregar así:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System;
using System.Linq;

namespace RestFullMinimalApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Retrieves WeatherForecast
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string Summary { get; set; }
    }
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System;
using System.Linq;

namespace RestFullMinimalApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Retrieves WeatherForecast
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string Summary { get; set; }
    }
}
Imports Microsoft.AspNetCore.Mvc
Imports Microsoft.Extensions.Logging
Imports System.Collections.Generic
Imports System
Imports System.Linq

Namespace RestFullMinimalApi.Controllers
	<ApiController>
	<Route("[controller]")>
	Public Class WeatherForecastController
		Inherits ControllerBase

		Private Shared ReadOnly Summaries() As String = { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }

		Private ReadOnly _logger As ILogger(Of WeatherForecastController)

		Public Sub New(ByVal logger As ILogger(Of WeatherForecastController))
			_logger = logger
		End Sub

		''' <summary>
		''' Retrieves WeatherForecast
		''' </summary>
		''' <remarks>Awesomeness!</remarks>
		''' <response code="200">Retrieved</response>
		''' <response code="404">Not found</response>
		''' <response code="500">Oops! Can't lookup your request right now</response>
		<HttpGet(Name := "GetWeatherForecast")>
		Public Function [Get]() As IEnumerable(Of WeatherForecast)
			Return Enumerable.Range(1, 5).Select(Function(index) New WeatherForecast With {
				.Date = DateTime.Now.AddDays(index),
				.TemperatureC = Random.Shared.Next(-20, 55),
				.Summary = Summaries(Random.Shared.Next(Summaries.Length))
			}).ToArray()
		End Function
	End Class

	Public Class WeatherForecast
		Public Property [Date]() As DateTime
		Public Property TemperatureC() As Integer
		Public Property Summary() As String
	End Class
End Namespace
$vbLabelText   $csharpLabel

El código anterior está disponible en GitHub - Demo de Swashbuckle.

Swashbuckle ofrece las siguientes características

Herramienta de interfaz de usuario Swagger

![Swashbuckle ASP .NET Core (Cómo Funciona Para Desarrolladores): Figura 1 - Herramienta Swagger UI

Swagger UI está disponible en "/swagger/index.html" desde la URL base de la aplicación de API web. Lista todas las APIs REST del código. El generador de Swagger lee el archivo JSON y rellena la interfaz de usuario.

Swagger JSON

Swashbuckle.AspNetCore genera automáticamente el archivo JSON de Swagger, que contiene información sobre la estructura de la API, incluyendo detalles como endpoints, tipos de solicitud y respuesta, y más. Este archivo JSON puede ser utilizado por otras herramientas y servicios que admiten el estándar Swagger/OpenAPI.

El archivo JSON de Swagger está disponible en "/swagger/v1/swagger.json" desde la URL base de la aplicación API web.

![Swashbuckle ASP .NET Core (Cómo Funciona Para Desarrolladores): Figura 2 - El archivo JSON de Swagger.

Anotaciones de código

Los desarrolladores pueden usar comentarios y atributos XML dentro de sus controladores de ASP.NET Core para proporcionar información adicional para la documentación de Swagger. Esto incluye descripciones, ejemplos y otros metadatos que mejoran la documentación generada de Swagger.

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Retrieves WeatherForecast
    /// </summary>
    /// <remarks>Awesomeness!</remarks>
    /// <response code="200">Retrieved</response>
    /// <response code="404">Not found</response>
    /// <response code="500">Oops! Can't lookup your request right now</response>
    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }
}
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Retrieves WeatherForecast
    /// </summary>
    /// <remarks>Awesomeness!</remarks>
    /// <response code="200">Retrieved</response>
    /// <response code="404">Not found</response>
    /// <response code="500">Oops! Can't lookup your request right now</response>
    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }
}
<ApiController>
<Route("[controller]")>
Public Class WeatherForecastController
	Inherits ControllerBase

	Private Shared ReadOnly Summaries() As String = { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }

	Private ReadOnly _logger As ILogger(Of WeatherForecastController)

	Public Sub New(ByVal logger As ILogger(Of WeatherForecastController))
		_logger = logger
	End Sub

	''' <summary>
	''' Retrieves WeatherForecast
	''' </summary>
	''' <remarks>Awesomeness!</remarks>
	''' <response code="200">Retrieved</response>
	''' <response code="404">Not found</response>
	''' <response code="500">Oops! Can't lookup your request right now</response>
	<HttpGet(Name := "GetWeatherForecast")>
	Public Function [Get]() As IEnumerable(Of WeatherForecast)
		Return Enumerable.Range(1, 5).Select(Function(index) New WeatherForecast With {
			.Date = DateTime.Now.AddDays(index),
			.TemperatureC = Random.Shared.Next(-20, 55),
			.Summary = Summaries(Random.Shared.Next(Summaries.Length))
		}).ToArray()
	End Function
End Class
$vbLabelText   $csharpLabel

Opciones de configuración

Swashbuckle.AspNetCore ofrece varias opciones de configuración para personalizar cómo se genera la documentación de Swagger. Los desarrolladores pueden controlar qué APIs se documentan, configurar convenciones de nomenclatura y ajustar otras configuraciones.

Aquí hay algunas de las principales opciones de configuración proporcionadas por Swashbuckle.AspNetCore:

Opciones de SwaggerGen

c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.SwaggerDoc("v1", New OpenApiInfo With {
	.Title = "My API",
	.Version = "v1"
})
$vbLabelText   $csharpLabel

Esta línea especifica la versión del documento Swagger e incluye metadatos como el título y la versión de su API.

c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath)
$vbLabelText   $csharpLabel

Esta opción permite incluir comentarios XML de su código para proporcionar información adicional en la documentación de Swagger. La variable xmlPath debe apuntar a la ubicación de su archivo de comentarios XML.

c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase()
$vbLabelText   $csharpLabel

Esta opción configura el generador de Swagger para usar camelCase para nombres de parámetros.

c.OperationFilter<CustomOperationFilter>();
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter(Of CustomOperationFilter)()
$vbLabelText   $csharpLabel

Puede registrar filtros de operación personalizados para modificar la documentación de Swagger para operaciones específicas. CustomOperationFilter es una clase que implementa IOperationFilter.

Opciones de la interfaz de usuario de Swagger

c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")
$vbLabelText   $csharpLabel

Esta línea configura el Swagger UI para mostrar documentación. El primer parámetro es la URL del archivo JSON de Swagger, y el segundo parámetro es un nombre amigable para la versión de la API.

c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger"
$vbLabelText   $csharpLabel

Puede establecer el prefijo de ruta para el Swagger UI. En este ejemplo, el Swagger UI estará disponible en /swagger.

c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None)
$vbLabelText   $csharpLabel

Esta opción controla cómo el Swagger UI muestra la documentación de la API. DocExpansion.None colapsa todas las operaciones por defecto.

SwaggerOptions

c.SerializeAsV2 = true;
c.SerializeAsV2 = true;
c.SerializeAsV2 = True
$vbLabelText   $csharpLabel

Esta opción especifica si se debe serializar el documento Swagger en formato versión 2.0 (true) o versión 3.0 (false). Establézcalo en true si desea usar Swagger 2.0.

c.DisplayOperationId();
c.DisplayOperationId();
c.DisplayOperationId()
$vbLabelText   $csharpLabel

Esta opción muestra el ID de operación en el Swagger UI, lo cual puede ser útil para depurar y entender la estructura de su API.

c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui")
$vbLabelText   $csharpLabel

Si su API utiliza autenticación OAuth, puede configurar el ID del cliente OAuth para Swagger UI.

Estos son solo algunos ejemplos de las opciones de configuración disponibles. La biblioteca Swashbuckle.AspNetCore es altamente personalizable, y puede adaptar la documentación de Swagger para satisfacer sus necesidades específicas combinando varias opciones y filtros. Siempre refiérase a la documentación oficial o a IntelliSense en su entorno de desarrollo para obtener la información más actualizada y completa sobre las opciones disponibles.

Presentación de IronPDF

IronPDF Product Overview es la Biblioteca PDF para C# de Iron Software Website que ayuda a leer y generar documentos PDF. Puede convertir fácilmente documentos formateados con información de estilo a PDF. IronPDF puede generar sin esfuerzo PDFs a partir de contenido HTML. Puede descargar el contenido HTML desde una URL y luego generar PDFs.

IronPDF es una gran herramienta para convertir páginas web, URLs y HTML en PDFs que replican perfectamente la fuente. Es ideal para generar PDFs de contenido en línea como reportes y facturas, y crea sin esfuerzo versiones en PDF de cualquier página web.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Instalación

Instale IronPDF a través de NuGet usando los Detalles del Administrador de Paquetes NuGet o la consola del Guía de Instalación de Visual Studio administrador de paquetes.

En la Consola del Administrador de Paquetes, ingrese el comando:

Install-Package IronPdf

Usando Visual Studio

Swashbuckle ASP .NET Core (Cómo Funciona Para Desarrolladores): Figura 3 - Abra su proyecto en Visual Studio. Vaya al menú Herramientas, seleccione Administrador de Paquetes NuGet, luego seleccione Administrar Paquetes NuGet para la Solución. En la interfaz del Administrador de Paquetes NuGet, busque el paquete IronPDF en la pestaña de Búsqueda. Luego seleccione e instale la última versión de IronPDF.

Ahora, modifiquemos nuestra aplicación para agregar funcionalidad para descargar contenido de sitios web como un archivo PDF.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace RestFullMinimalApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Retrieves WeatherForecast
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

        /// <summary>
        /// Retrieves WeatherForecast as Pdf
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet("download", Name = "DownloadWeatherForecast")]
        public IActionResult GetWeatherPdf()
        {
            var results = Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            }).ToArray();

            var html = GetHtml(results);
            var renderer = new ChromePdfRenderer();
            var pdf = renderer.RenderHtmlAsPdf(html);
            var fileName = "WeatherReport.pdf";
            pdf.SaveAs(fileName);

            var stream = new FileStream(fileName, FileMode.Open);
            // Return the PDF file for download
            return new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = fileName };
        }

        private static string GetHtml(WeatherForecast[] weatherForecasts)
        {
            string header = @"
<html>
<head><title>WeatherForecast</title></head>
<body>
<h1>WeatherForecast</h1>
";

            var footer = @"
</body>
</html>";

            var htmlContent = header;
            foreach (var weather in weatherForecasts)
            {
                htmlContent += $@"
    <h2>{weather.Date}</h2>
    <p>Summary: {weather.Summary}</p>
    <p>Temperature in Celsius: {weather.TemperatureC}</p>
    <p>Temperature in Fahrenheit: {weather.TemperatureF}</p>
";
            }
            htmlContent += footer;
            return htmlContent;
        }
    }

    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string Summary { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace RestFullMinimalApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// Retrieves WeatherForecast
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

        /// <summary>
        /// Retrieves WeatherForecast as Pdf
        /// </summary>
        /// <remarks>Awesomeness!</remarks>
        /// <response code="200">Retrieved</response>
        /// <response code="404">Not found</response>
        /// <response code="500">Oops! Can't lookup your request right now</response>
        [HttpGet("download", Name = "DownloadWeatherForecast")]
        public IActionResult GetWeatherPdf()
        {
            var results = Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            }).ToArray();

            var html = GetHtml(results);
            var renderer = new ChromePdfRenderer();
            var pdf = renderer.RenderHtmlAsPdf(html);
            var fileName = "WeatherReport.pdf";
            pdf.SaveAs(fileName);

            var stream = new FileStream(fileName, FileMode.Open);
            // Return the PDF file for download
            return new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = fileName };
        }

        private static string GetHtml(WeatherForecast[] weatherForecasts)
        {
            string header = @"
<html>
<head><title>WeatherForecast</title></head>
<body>
<h1>WeatherForecast</h1>
";

            var footer = @"
</body>
</html>";

            var htmlContent = header;
            foreach (var weather in weatherForecasts)
            {
                htmlContent += $@"
    <h2>{weather.Date}</h2>
    <p>Summary: {weather.Summary}</p>
    <p>Temperature in Celsius: {weather.TemperatureC}</p>
    <p>Temperature in Fahrenheit: {weather.TemperatureF}</p>
";
            }
            htmlContent += footer;
            return htmlContent;
        }
    }

    public class WeatherForecast
    {
        public DateTime Date { get; set; }
        public int TemperatureC { get; set; }
        public string Summary { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}
Imports Microsoft.AspNetCore.Mvc
Imports Microsoft.Extensions.Logging
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq

Namespace RestFullMinimalApi.Controllers
	<ApiController>
	<Route("[controller]")>
	Public Class WeatherForecastController
		Inherits ControllerBase

		Private Shared ReadOnly Summaries() As String = { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }

		Private ReadOnly _logger As ILogger(Of WeatherForecastController)

		Public Sub New(ByVal logger As ILogger(Of WeatherForecastController))
			_logger = logger
		End Sub

		''' <summary>
		''' Retrieves WeatherForecast
		''' </summary>
		''' <remarks>Awesomeness!</remarks>
		''' <response code="200">Retrieved</response>
		''' <response code="404">Not found</response>
		''' <response code="500">Oops! Can't lookup your request right now</response>
		<HttpGet(Name := "GetWeatherForecast")>
		Public Function [Get]() As IEnumerable(Of WeatherForecast)
			Return Enumerable.Range(1, 5).Select(Function(index) New WeatherForecast With {
				.Date = DateTime.Now.AddDays(index),
				.TemperatureC = Random.Shared.Next(-20, 55),
				.Summary = Summaries(Random.Shared.Next(Summaries.Length))
			}).ToArray()
		End Function

		''' <summary>
		''' Retrieves WeatherForecast as Pdf
		''' </summary>
		''' <remarks>Awesomeness!</remarks>
		''' <response code="200">Retrieved</response>
		''' <response code="404">Not found</response>
		''' <response code="500">Oops! Can't lookup your request right now</response>
		<HttpGet("download", Name := "DownloadWeatherForecast")>
		Public Function GetWeatherPdf() As IActionResult
			Dim results = Enumerable.Range(1, 5).Select(Function(index) New WeatherForecast With {
				.Date = DateTime.Now.AddDays(index),
				.TemperatureC = Random.Shared.Next(-20, 55),
				.Summary = Summaries(Random.Shared.Next(Summaries.Length))
			}).ToArray()

			Dim html = GetHtml(results)
			Dim renderer = New ChromePdfRenderer()
			Dim pdf = renderer.RenderHtmlAsPdf(html)
			Dim fileName = "WeatherReport.pdf"
			pdf.SaveAs(fileName)

			Dim stream = New FileStream(fileName, FileMode.Open)
			' Return the PDF file for download
			Return New FileStreamResult(stream, "application/octet-stream") With {.FileDownloadName = fileName}
		End Function

		Private Shared Function GetHtml(ByVal weatherForecasts() As WeatherForecast) As String
			Dim header As String = "
<html>
<head><title>WeatherForecast</title></head>
<body>
<h1>WeatherForecast</h1>
"

			Dim footer = "
</body>
</html>"

			Dim htmlContent = header
			For Each weather In weatherForecasts
				htmlContent &= $"
    <h2>{weather.Date}</h2>
    <p>Summary: {weather.Summary}</p>
    <p>Temperature in Celsius: {weather.TemperatureC}</p>
    <p>Temperature in Fahrenheit: {weather.TemperatureF}</p>
"
			Next weather
			htmlContent &= footer
			Return htmlContent
		End Function
	End Class

	Public Class WeatherForecast
		Public Property [Date]() As DateTime
		Public Property TemperatureC() As Integer
		Public Property Summary() As String

		Public ReadOnly Property TemperatureF() As Integer
			Get
				Return 32 + CInt(Math.Truncate(TemperatureC / 0.5556))
			End Get
		End Property
	End Class
End Namespace
$vbLabelText   $csharpLabel

Aquí, usamos los datos del clima para generar una cadena de HTML, que luego se usa para crear un documento PDF.

Contenido HTML

![Swashbuckle ASP .NET Core (Cómo Funciona Para Desarrolladores): Figura 4 - Contenido HTML para Pronóstico del Tiempo.

Y el informe PDF se ve así:

![Swashbuckle ASP .NET Core (Cómo Funciona Para Desarrolladores): Figura 5 - Archivo de salida de HTML a PDF: WeatherReport.pdf

Todo el código puede encontrarse en GitHub - Código Fuente de Demo Swashbuckle.
El documento tiene una pequeña marca de agua para licencias de prueba, eliminable con una licencia válida.

Licencia (Prueba gratuita disponible)

Para que funcione el código anterior, se requiere una clave de licencia. Coloque esta clave en el archivo appsettings.json.

{
    "IronPdf": {
        "LicenseKey": "your license key"
    }
}

Una licencia de prueba está disponible para desarrolladores al registrarse en Registro de Prueba de IronPDF. No se necesita tarjeta de crédito para una licencia de prueba. Regístrese con su dirección de correo electrónico para obtener una prueba gratuita.

Conclusión

Comprender Swashbuckle e IronPDF le permite integrar efectivamente capacidades de documentación de API y generación de PDF en sus aplicaciones ASP.NET Core. IronPDF también ofrece documentación completa para Comenzar, junto con varios Ejemplos de Código para Generación de PDF.

Además, puede explorar productos de software relacionados de Iron Software que le ayudarán a mejorar sus habilidades de codificación y cumplir con los requisitos modernos para aplicaciones.

Preguntas Frecuentes

¿Cómo puedo documentar Web APIs RESTful usando Swashbuckle en ASP.NET Core?

Swashbuckle puede usarse para documentar Web APIs RESTful generando documentación Swagger a partir de comentarios XML en el código. Necesitas instalar el paquete Swashbuckle.AspNetCore y configurarlo en el archivo `Startup.cs` de tu proyecto ASP.NET Core.

¿Cuáles son los pasos para configurar Swashbuckle en un nuevo proyecto de ASP.NET Core Web API?

Para configurar Swashbuckle, comienza instalando el paquete NuGet Swashbuckle.AspNetCore. Luego, configura el middleware de Swagger en el archivo `Startup.cs` agregando `services.AddSwaggerGen()` en el método `ConfigureServices` y `app.UseSwagger()` junto con `app.UseSwaggerUI()` en el método `Configure`.

¿Cómo puedo convertir contenido HTML a un PDF en una aplicación .NET Core?

Puedes convertir contenido HTML a PDF en una aplicación .NET Core usando IronPDF. Esta biblioteca te permite convertir cadenas HTML, archivos y URLs en documentos PDF usando métodos como `RenderHtmlAsPdf` y `RenderUrlAsPdf`.

¿Cuáles son los beneficios de usar Swashbuckle en el desarrollo de APIs?

Swashbuckle simplifica la documentación de APIs generando automáticamente documentación compatible con Swagger, lo que ayuda a mantener claros y consistentes los estándares de documentación de la API. También proporciona una interfaz amigable para explorar y probar APIs a través de Swagger UI.

¿Cómo integro capacidades de generación de PDF en un proyecto ASP.NET Core?

La integración de generación de PDFs en un proyecto ASP.NET Core puede lograrse mediante el uso de IronPDF. Instala la biblioteca IronPDF a través de NuGet y utiliza sus métodos para generar PDFs a partir de varios tipos de contenido. Asegúrate de que tu proyecto incluya las directivas de uso necesarias y cualquier llave de licencia.

¿Qué opciones de configuración están disponibles para personalizar la documentación Swagger en Swashbuckle?

Swashbuckle ofrece varias opciones de configuración para personalizar la documentación Swagger, incluyendo la configuración de versionado de API, habilitar comentarios XML, definir convenciones de nomenclatura de parámetros, y personalizar la apariencia y comportamiento de Swagger UI.

¿Cómo puedo solucionar problemas comunes al usar Swashbuckle en un proyecto ASP.NET Core?

Los problemas comunes con Swashbuckle pueden abordarse asegurando que la documentación XML esté habilitada en las propiedades del proyecto, verificando las versiones correctas de los paquetes, y asegurándose de la configuración correcta en el archivo `Startup.cs`, incluyendo el orden adecuado del middleware.

¿Cuáles son algunas características de IronPDF para generar PDFs en C#?

IronPDF ofrece características como la conversión de contenido HTML, URLs y contenido ASP.NET a PDF, agregar encabezados y pies de página, fusionar PDFs y manipular archivos PDF existentes. Es una biblioteca integral para manejar operaciones de PDF en proyectos C#.

¿Cómo admite IronPDF el licenciamiento para uso comercial?

IronPDF admite el licenciamiento mediante una llave de licencia comercial. Puedes probar IronPDF con una prueba gratuita e incluir la llave de licencia en la configuración de tu proyecto, típicamente dentro del archivo `appsettings.json`, bajo la sección `IronPdf`.

Jacob Mellor, Director de Tecnología @ Team Iron
Director de Tecnología

Jacob Mellor es Director de Tecnología en Iron Software y un ingeniero visionario que lidera la tecnología PDF en C#. Como el desarrollador original detrás de la base de código central de Iron Software, ha moldeado la arquitectura de productos de la compañía desde ...

Leer más