Pruebas en un entorno real
Pruebe en producción sin marcas de agua.
Funciona donde lo necesites.
Swashbuckle es un núcleo C# .NET NuGet que ayuda a documentar automáticamente las API web RESTful desarrolladas. En este blog, vamos a explorar Swashbuckle ASP.NET core y IronPDF Paquetes NuGet, que permitirán el desarrollo de aplicaciones modernas de ASP.NET Core Web API. Juntos permiten una gran cantidad de funcionalidades que pueden lograrse con una cantidad mínima de código.
Las páginas de documentación de la API se muestran utilizando la herramienta swagger UI que utiliza swagger.json que se genera a partir del proyecto web API. El documento JSON generado sigue el estándar de API abierta. El Swashbuckle está disponible como paquete NuGget Swashbuckle.AspNetCore que una vez instalado y configurado, expondrá automáticamente swagger JSON. La herramienta swagger UI lee el archivo swagger JSON, que se genera a partir de los 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 swagger JSON. A continuación, el middleware swagger lee el JSON y expone puntos finales JSON swagger.
Empecemos con el proyecto Web API
dotnet new webapi -n SwashbuckleDemo
cd Swashbuckle
dotnet build
dotnet add package --version 6.5.0 Swashbuckle.AspNetCore
dotnet build
dotnet new webapi -n SwashbuckleDemo
cd Swashbuckle
dotnet build
dotnet add package --version 6.5.0 Swashbuckle.AspNetCore
dotnet build
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet New webapi -n SwashbuckleDemo cd Swashbuckle dotnet build dotnet add package --version 6.5.0 Swashbuckle.AspNetCore dotnet build
Aquí estamos creando un proyecto de API web "SwashbuckleDemo" y luego instalar swashbuckle paquete para .NET Core Web API proyecto de la consola del gestor de paquetes.
Configure los servicios Swagger en el archivo Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
// Other service configurations...
// swagger ui components
// 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 static file middleware to serve Swagger UI (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
public void ConfigureServices(IServiceCollection services)
{
// Other service configurations...
// swagger ui components
// 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 static file middleware to serve Swagger UI (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
Public Sub ConfigureServices(ByVal services As IServiceCollection)
' Other service configurations...
' swagger ui components
' 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 static file middleware to serve 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
Añade también un controlador para las API de listas de tareas
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.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.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)
También se puede añadir un controlador como se indica a continuación:
using Microsoft.AspNetCore.Mvc;
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();
}
}
using Microsoft.AspNetCore.Mvc;
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();
}
}
Imports Microsoft.AspNetCore.Mvc
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
End Namespace
El código anterior está disponible en GitHub.
Swagger UI está disponible en "/swagger/index.html" desde la URL base de la aplicación Web API. Enumera todas las API REST del código. El generador swagger lee el archivo JSON y rellena la interfaz de usuario.
Swashbuckle.AspNetCore genera automáticamente el archivo JSON Swagger, que contiene información sobre la estructura de la API, incluidos detalles como los puntos finales, los tipos de solicitud y respuesta, etc. Este archivo JSON puede ser utilizado por otras herramientas y servicios que soporten el estándar Swagger/OpenAPI.
El archivo swagger JSON está disponible en "/swagger/v1/swagger.json" desde la URL base de la aplicación de la API web.
Los desarrolladores pueden utilizar comentarios y atributos XML dentro de sus ASP.NET Controladores principales para proporcionar información adicional para la documentación swagger. Esto incluye descripciones, ejemplos y otros metadatos que mejoran la documentación Swagger generada.
[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
Swashbuckle.AspNetCore proporciona varias opciones de configuración para personalizar cómo se genera la documentación Swagger. Los desarrolladores pueden controlar qué API están documentadas, configurar las convenciones de nomenclatura y ajustar otros parámetros.
Éstas son algunas de las principales opciones de configuración proporcionadas por Swashbuckle.AspNetCore:
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"
})
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)
Esta opción le permite incluir comentarios XML de su código para proporcionar información adicional en la documentación Swagger. La variable xmlPath debe apuntar a la ubicación de su archivo de comentarios XML.
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase()
Esta opción configura el generador Swagger para que utilice camel Case en los nombres de los parámetros.
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter(Of CustomOperationFilter)()
Puede registrar filtros de operación personalizados para modificar la documentación Swagger para operaciones específicas. CustomOperationFilter es una clase que implementa IOperationFilter.
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")
Esta línea configura la interfaz de usuario Swagger para mostrar la documentación. El primer parámetro es la URL del archivo JSON de Swagger, y el segundo es un nombre fácil de usar para la versión de la API.
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger"
Puede establecer el prefijo de ruta para la interfaz de usuario Swagger. En este ejemplo, la interfaz de usuario de Swagger estará disponible en /swagger.
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None)
Esta opción controla cómo la interfaz de usuario Swagger muestra la documentación de la API. DocExpansion.None contrae todas las operaciones por defecto.
c.SerializeAsV2 = true;
c.SerializeAsV2 = true;
c.SerializeAsV2 = True
Esta opción especifica si serializar el documento Swagger en formato versión 2.0 (verdadero) o formato 3.0 (falso). Establézcalo a true si desea utilizar Swagger 2.0.
c.DisplayOperationId();
c.DisplayOperationId();
c.DisplayOperationId()
Esta opción muestra el ID de la operación en la interfaz de usuario Swagger, lo que puede ser útil para depurar y comprender la estructura de su API.
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui")
Si su API utiliza autenticación OAuth, puede configurar el ID de cliente OAuth para Swagger UI.
Estos son sólo algunos ejemplos de las opciones de configuración disponibles. La biblioteca Swashbuckle.AspNetCore es altamente personalizable, y puede adaptar la documentación Swagger para satisfacer sus necesidades específicas mediante la combinación de varias opciones y filtros. Consulte siempre la documentación oficial o IntelliSense en su entorno de desarrollo para obtener la información más actualizada y completa sobre las opciones disponibles.
IronPDF es la biblioteca PDF en C# de Iron Software que ayuda a leer y generar documentos PDF. Puede convertir fácilmente documentos formateados con información de estilo a PDF. IronPDF puede generar fácilmente archivos PDF a partir de contenido HTML. Puede descargar el contenido HTML de la URL y luego generar PDF.
IronPDF puede instalarse mediante Paquete NuGet Manager o utilizando el Visual Studio Consola del gestor de paquetes.
En la consola del gestor de paquetes, introduzca el comando:
Install-Package IronPdf
Uso de Visual Studio
Ahora, vamos a modificar nuestra aplicación para añadir la funcionalidad de descargar el contenido de un sitio web como un archivo PDF.
using Microsoft.AspNetCore.Mvc;
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 GetWeatherExcel()
{
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);
// Save the excel file
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 Celcius: {weather.TemperatureC}</p>
<p>Temperature in Farenheit: {weather.TemperatureF}</p>
";
}
htmlContent += footer;
return htmlContent;
}
}
using Microsoft.AspNetCore.Mvc;
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 GetWeatherExcel()
{
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);
// Save the excel file
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 Celcius: {weather.TemperatureC}</p>
<p>Temperature in Farenheit: {weather.TemperatureF}</p>
";
}
htmlContent += footer;
return htmlContent;
}
}
Imports Microsoft.AspNetCore.Mvc
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 GetWeatherExcel() 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)
' Save the excel file
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>
"
ignore ignore ignore ignore ignore var footer = "
</body>
</html>"
ignore ignore var htmlContent = header
For Each weather In weatherForecasts
htmlContent += $"
<h2>{weather.Date}</h2>
<p>Summary: {weather.Summary}</p>
<p>Temperature in Celcius: {weather.TemperatureC}</p>
<p>Temperature in Farenheit: {weather.TemperatureF}</p>
"
ignore ignore ignore ignore ignore
Next weather
htmlContent += footer
Return htmlContent
End Function
End Class
End Namespace
Aquí estamos utilizando los datos meteorológicos para generar una cadena HTML y luego esta cadena se utiliza para generar el documento PDF.
Y el informe en PDF tiene este aspecto:
El código completo puede consultarse en GitHub aquí. El documento tiene una pequeña marca de agua para las licencias de prueba y puede eliminarse con una licencia válida.
Para que el código anterior funcione, se necesita una clave de licencia. Esta clave debe colocarse en el archivo appsettings.json.
"IronPdf.LicenseKey": "your license key"
"IronPdf.LicenseKey": "your license key"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'"IronPdf.LicenseKey": "your license key"
Los desarrolladores pueden obtener una licencia de prueba al registrarse. aquí y sí, no se necesita tarjeta de crédito para una licencia de prueba. Se puede facilitar la dirección de correo electrónico y registrarse para una prueba gratuita.
Swashbuckle. IronPDF también ofrece una documentación adecuada sobre cómo empezarjunto con varios ejemplos de código.
También puede explorar otros productos de software de Iron Software que le ayudará a mejorar sus habilidades de codificación y a cumplir los requisitos de las aplicaciones modernas.
9 productos API .NET para sus documentos de oficina