.NET 帮助

Swashbuckle ASP .NET Core(它如何为开发人员工作)

发布 2024年一月27日
分享:

简介

Swashbuckle 是一款 C# .NET core NuGet 包,它有助于自动记录所开发的 RESTful Web API。在本博客中,我们将探讨 Swashbuckle ASP.NET core 和 IronPDF NuGet 软件包将使 ASP.NET Core Web API 的现代应用程序开发成为可能。通过这些软件包,可以用最少的代码实现大量功能。

API 文档页面使用 swagger UI 工具显示,该工具使用从 Web API 项目生成的 swagger.json。生成的 JSON 文档遵循开放 API 标准。Swashbuckle 可作为 NuGget 软件包使用 Swashbuckle.AspNetCore 安装和配置后,将自动公开 swagger JSON。swagger UI 工具会读取由写在 API 上的 XML 注释生成的 swagger JSON 文件。此外,还可以通过在项目设置文件中启用 XML 文档文件来创建 XML 文档文件。XML 注释会被转换为 XML 文档文件,并从中生成 swagger JSON。然后,swagger 中间件读取 JSON 并公开 swagger JSON 端点。

在 .NET Core Web API 项目中实施

让我们从 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
VB   C#

在这里,我们要创建一个 Web API 项目 "SwashbuckleDemo",然后从软件包管理器控制台为 .NET Core Web API 项目安装 swashbuckle 软件包。

配置 Swagger 中间件

在 Startup.cs 文件中配置 Swagger 服务。

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
VB   C#

还为待办事项列表 API 添加了一个控制器

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)
VB   C#

也可以像下面这样添加控制器:

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
VB   C#

上述代码可在 GitHub.

Swashbuckle 提供以下功能

Swagger UI 工具

Swashbuckle ASP .NET Core(如何为开发人员工作):图 1 - Swagger UI 工具

Swagger UI 位于 Web API 应用程序基本 URL 的"/swagger/index.html "处。它列出了代码中的所有 REST API。Swagger 生成器会读取 JSON 文件并填充用户界面。

Swagger JSON

Swashbuckle.AspNetCore 会自动生成 Swagger JSON 文件,其中包含有关 API 结构的信息,包括端点、请求和响应类型等详细信息。支持 Swagger/OpenAPI 标准的其他工具和服务可以使用该 JSON 文件。

swagger JSON 文件可从网络 API 应用程序的基本 URL"/swagger/v1/swagger.json "中获取。

Swashbuckle ASP .NET Core(如何为开发人员工作):图 2 - swagger JSON 文件。

代码注释

开发人员可以在他们的 ASP.NET 核心控制器为 Swagger 文档提供附加信息。这包括描述、示例和其他元数据,可增强生成的 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
VB   C#

配置选项

Swashbuckle.AspNetCore 提供各种配置选项,用于自定义 Swagger 文档的生成方式。开发人员可以控制哪些 API 被记录、配置命名约定并调整其他设置。

以下是 Swashbuckle.AspNetCore 提供的一些关键配置选项:

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"
})
VB   C#

此行指定 Swagger 文档版本,并包含 API 的标题和版本等元数据。

c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath);
c.IncludeXmlComments(xmlPath)
VB   C#

该选项允许您在代码中加入 XML 注释,以便在 Swagger 文档中提供更多信息。xmlPath 变量应指向 XML 注释文件的位置。

c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase();
c.DescribeAllParametersInCamelCase()
VB   C#

该选项可将 Swagger 生成器配置为使用驼峰 Case 作为参数名。

c.OperationFilter<CustomOperationFilter>();
c.OperationFilter<CustomOperationFilter>();
c.OperationFilter(Of CustomOperationFilter)()
VB   C#

您可以注册自定义操作过滤器来修改特定操作的 Swagger 文档。CustomOperationFilter 是一个实现 IOperationFilter 的类。

Swagger UI 选项

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")
VB   C#

此行配置 Swagger UI 以显示文档。第一个参数是 Swagger JSON 文件的 URL,第二个参数是用户友好的 API 版本名称。

c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger";
c.RoutePrefix = "swagger"
VB   C#

您可以为 Swagger UI 设置路由前缀。在本例中,Swagger UI 将在 /swagger 上可用。

c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None);
c.DocExpansion(DocExpansion.None)
VB   C#

该选项控制 Swagger UI 显示 API 文档的方式。默认情况下,DocExpansion.None 会折叠所有操作。

SwaggerOptions

c.SerializeAsV2 = true;
c.SerializeAsV2 = true;
c.SerializeAsV2 = True
VB   C#

该选项指定是否以 2.0 版格式序列化 Swagger 文档 (真) 或 3.0 格式 (错误).如果要使用 Swagger 2.0,请将其设置为 true。

c.DisplayOperationId();
c.DisplayOperationId();
c.DisplayOperationId()
VB   C#

该选项可在 Swagger UI 中显示操作 ID,这对于调试和了解 API 结构非常有用。

c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui");
c.OAuthClientId("swagger-ui")
VB   C#

如果您的 API 使用 OAuth 身份验证,您可以为 Swagger UI 配置 OAuth 客户端 ID。

以上只是可用配置选项的几个示例。Swashbuckle.AspNetCore 库具有高度可定制性,您可以通过组合各种选项和过滤器来定制 Swagger 文档,以满足您的特定需求。有关可用选项的最新综合信息,请务必参考官方文档或开发环境中的 IntelliSense。

介绍 IronPDF

IronPDF 是来自 铁软件 它有助于阅读和生成 PDF 文档。它能轻松地将带有样式信息的格式化文档转换为 PDF。IronPDF 可以轻松地从 HTML 内容生成 PDF。它可以从 URL 下载 HTML 内容,然后生成 PDF。

安装

IronPDF 可以使用 NuGet 软件包 管理器或使用 Visual Studio 软件包管理器控制台。

在软件包管理器控制台中输入命令:

Install-Package IronPdf

使用 Visual Studio

Swashbuckle ASP .NET Core(如何为开发人员工作):图 3 - 在 Visual Studio 中打开项目。转到 "Tools" 菜单,选择 "NuGet Package Manager",然后选择 "Manage NuGet Packages for Solution"。在 NuGet 包管理器界面中,在 浏览 选项卡中搜索包 "ironpdf"。然后选择并安装最新版本的 IronPDF。

现在,让我们修改应用程序,添加将网站内容下载为 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
VB   C#

在这里,我们使用天气数据生成 HTML 字符串,然后使用该字符串生成 PDF 文档。

HTML 内容

Swashbuckle ASP .NET Core(如何为开发人员工作):图 4 - 天气预报的 HTML 内容。

PDF 报告看起来是这样的

Swashbuckle ASP .NET Core(如何为开发人员工作):图 5 - HTML 转 PDF 输出文件:WeatherReport.pdf

整个代码可在 GitHub 上找到 这里.

文件上有一个试用许可证的小水印,可使用有效许可证去除。

许可 (可免费试用)

要使上述代码正常工作,需要许可证密钥。该密钥需要放在 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"
VB   C#

开发人员注册后可获得试用许可证 这里 是的,试用许可证无需信用卡。用户只需提供电子邮件地址,即可注册免费试用。

结论

Swashbuckle.IronPDF 还提供了关于以下方面的适当文档 如何开始与各种 代码示例.

此外,您还可以从 铁软件 它将帮助你提高编码技能,满足现代应用程序的要求。

< 前一页
C# 计时器(它是如何为开发人员工作的)
下一步 >
NPlot C# (如何为开发者工作) | IronPDF

准备开始了吗? 版本: 2024.9 刚刚发布

免费NuGet下载 总下载量: 10,731,156 查看许可证 >