Test dans un environnement réel
Test en production sans filigrane.
Fonctionne partout où vous en avez besoin.
Swashbuckle est une application C# .NET core NuGet qui permet de documenter automatiquement les API Web RESTful développées. Dans ce blog, nous allons explorer Swashbuckle ASP.NET core et le système de gestion de l'information IronPDF Des packages NuGet, qui permettront le développement d'applications modernes de l'API Web ASP.NET Core. Ensemble, ils permettent une multitude de fonctionnalités qui peuvent être réalisées avec un minimum de code.
Les pages de documentation de l'API sont affichées à l'aide de l'outil swagger UI qui utilise le fichier swagger.json généré à partir du projet d'API Web. Le document JSON généré est conforme à la norme API ouverte. Le Swashbuckle est disponible sous forme de paquet NuGget Swashbuckle.AspNetCore qui, une fois installé et configuré, exposera automatiquement swagger JSON. L'outil swagger UI lit le fichier swagger JSON, qui est généré à partir des commentaires XML écrits sur les API. En outre, un fichier de documentation XML peut être créé en l'activant dans le fichier de configuration du projet. Les commentaires XML sont convertis en un fichier de documentation XML, à partir duquel swagger JSON est généré. Ensuite, l'intergiciel swagger lit le JSON et expose les points d'extrémité swagger JSON.
Commençons par un projet d'API Web
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
Ici, nous créons un projet d'API Web "SwashbuckleDemo", puis nous installons le paquet swashbuckle dans le projet d'API Web .NET Core à partir de la console du gestionnaire de paquets.
Configurer les services Swagger dans le fichier 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
Ajout d'un contrôleur pour les API de listes de choses à faire
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)
Un contrôleur peut également être ajouté comme ci-dessous :
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
Le code ci-dessus est disponible sur GitHub.
L'interface utilisateur Swagger est disponible à "/swagger/index.html" à partir de l'URL de base de l'application de l'API Web. Il répertorie toutes les API REST du code. Le générateur swagger lit le fichier JSON et remplit l'interface utilisateur.
Swashbuckle.AspNetCore génère automatiquement le fichier Swagger JSON, qui contient des informations sur la structure de l'API, y compris des détails tels que les points de terminaison, les types de demande et de réponse, et plus encore. Ce fichier JSON peut être utilisé par d'autres outils et services qui supportent le standard Swagger/OpenAPI.
Le fichier JSON de swagger est disponible à "/swagger/v1/swagger.json" à partir de l'URL de base de l'application web API.
Les développeurs peuvent utiliser des commentaires et des attributs XML dans leur ASP.NET Contrôleurs de base pour fournir des informations supplémentaires pour la documentation swagger. Il s'agit de descriptions, d'exemples et d'autres métadonnées qui améliorent la documentation Swagger générée.
[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 propose diverses options de configuration pour personnaliser la manière dont la documentation Swagger est générée. Les développeurs peuvent contrôler quelles API sont documentées, configurer les conventions de dénomination et ajuster d'autres paramètres.
Voici quelques-unes des principales options de configuration fournies par 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"
})
Cette ligne spécifie la version du document Swagger et inclut des métadonnées telles que le titre et la version de votre API.
c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath)
Cette option vous permet d'inclure des commentaires XML dans votre code afin de fournir des informations supplémentaires dans la documentation Swagger. La variable xmlPath doit pointer vers l'emplacement de votre fichier de commentaires XML.
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase()
Cette option configure le générateur Swagger pour qu'il utilise le camel case pour les noms de paramètres.
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter(Of CustomOperationFilter)()
Vous pouvez enregistrer des filtres d'opération personnalisés pour modifier la documentation Swagger pour des opérations spécifiques. CustomOperationFilter est une classe qui implémente 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")
Cette ligne configure l'interface utilisateur Swagger pour qu'elle affiche la documentation. Le premier paramètre est l'URL du fichier Swagger JSON, et le second paramètre est un nom convivial pour la version de l'API.
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger"
Vous pouvez définir le préfixe de l'itinéraire pour l'interface utilisateur Swagger. Dans cet exemple, l'interface utilisateur Swagger sera disponible à l'adresse /swagger.
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None)
Cette option permet de contrôler la manière dont l'interface utilisateur Swagger affiche la documentation de l'API. DocExpansion.None réduit toutes les opérations par défaut.
c.SerializeAsV2 = true;
c.SerializeAsV2 = true;
c.SerializeAsV2 = True
Cette option indique s'il faut sérialiser le document Swagger au format de la version 2.0 (vrai) ou 3.0 (faux). Mettez-le à true si vous voulez utiliser Swagger 2.0.
c.DisplayOperationId();
c.DisplayOperationId();
c.DisplayOperationId()
Cette option permet d'afficher l'identifiant de l'opération dans l'interface utilisateur Swagger, ce qui peut être utile pour le débogage et la compréhension de la structure de votre API.
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui")
Si votre API utilise l'authentification OAuth, vous pouvez configurer l'ID du client OAuth pour Swagger UI.
Il ne s'agit là que de quelques exemples des options de configuration disponibles. La bibliothèque Swashbuckle.AspNetCore est hautement personnalisable, et vous pouvez adapter la documentation Swagger à vos besoins spécifiques en combinant diverses options et filtres. Reportez-vous toujours à la documentation officielle ou à IntelliSense dans votre environnement de développement pour obtenir les informations les plus récentes et les plus complètes sur les options disponibles.
IronPDF est la bibliothèque PDF C# de Iron Software qui permet de lire et de générer des documents PDF. Il peut facilement convertir des documents formatés avec des informations de style en PDF. IronPDF peut facilement générer des PDF à partir de contenu HTML. Il peut télécharger le contenu HTML de l'URL et générer ensuite des PDF.
IronPDF peut être installé à l'aide de Paquet NuGet Ou en utilisant le Visual Studio Console du gestionnaire de paquets.
Dans la console du gestionnaire de paquets, entrez la commande :
Install-Package IronPdf
Utilisation de Visual Studio
Modifions maintenant notre application pour ajouter une fonctionnalité permettant de télécharger le contenu d'un site web au format 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
Ici, nous utilisons les données météorologiques pour générer une chaîne HTML, puis cette chaîne est utilisée pour générer le document PDF.
Le rapport PDF se présente comme suit :
L'ensemble du code est disponible sur GitHub ici.
Le document comporte un petit filigrane pour les licences d'essai et peut être supprimé à l'aide d'une licence valide.
Pour que le code ci-dessus fonctionne, une clé de licence est nécessaire. Cette clé doit être placée dans le fichier 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"
Une licence d'essai est disponible pour les développeurs lors de l'enregistrement ici et oui, aucune carte de crédit n'est nécessaire pour une licence d'essai. Il est possible de fournir l'adresse électronique et de s'inscrire pour un essai gratuit.
Casse-cou. IronPDF offre également une documentation appropriée sur comment commencer, ainsi que divers exemples de code.
Vous pouvez également découvrir d'autres produits logiciels de Iron Software qui vous aidera à améliorer vos compétences en matière de codage et à répondre aux exigences des applications modernes.
9 produits de l'API .NET pour vos documents de bureau