Przejdź do treści stopki
POMOC .NET

Swashbuckle .NET Core (jak to działa dla programistów)

Swashbuckle to pakiet NuGet dla C# .NET Core, który pomaga w automatycznej dokumentacji RESTful Web API. W tym blogu przyjrzymy się pakietom NuGet Swashbuckle ASP.NET Core i IronPDF Installation Instructions, umożliwiającym nowoczesne tworzenie interfejsów API ASP.NET Core. Razem zapewniają one szereg funkcji, które można osiągnąć przy minimalnej ilości kodu.

Strony dokumentacji API są wyświetlane za pomocą narzędzia Swagger UI, które wykorzystuje plik swagger.json wygenerowany z projektu Web API. Wygenerowany dokument JSON jest zgodny ze standardem Open API. Swashbuckle jest dostępne jako pakiet NuGet Swashbuckle.AspNetCore, który po zainstalowaniu i skonfigurowaniu automatycznie udostępni plik JSON Swagger. Narzędzie Swagger UI odczytuje plik Swagger JSON, wygenerowany na podstawie komentarzy XML zapisanych w interfejsach API. Dodatkowo można utworzyć plik dokumentacji XML, włączając tę opcję w pliku ustawień projektu. Komentarze XML są konwertowane na plik dokumentacji XML, na podstawie którego generowany jest plik Swagger JSON. Następnie oprogramowanie pośredniczące Swagger odczytuje plik JSON i udostępnia punkty końcowe Swagger JSON.

Wdrożenie w projekcie .NET Core Web API

Zacznijmy od projektu Web API:

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

W tym miejscu tworzymy projekt API sieci Web o nazwie "SwashbuckleDemo", a następnie instalujemy pakiet Swashbuckle w projekcie .NET Core Web API za pomocą konsoli menedżera pakietów.

Konfiguracja oprogramowania pośredniczącego Swagger

Skonfiguruj usługi Swagger w pliku 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

Dodaj kontroler dla interfejsów API listy zadań:

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

Można również dodać kontroler, jak poniżej:

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

Powyższy kod jest dostępny na GitHubie – Swashbuckle Demo.

Swashbuckle oferuje następujące funkcje

Narzędzie Swagger UI

Swashbuckle ASP .NET Core (jak to działa dla programisty): Rysunek 1 – narzędzie Swagger UI

Interfejs użytkownika Swagger jest dostępny pod adresem "/swagger/index.html" z podstawowego adresu URL aplikacji Web API. Zawiera listę wszystkich interfejsów API REST z kodu. Generator Swagger odczytuje plik JSON i wypełnia interfejs użytkownika.

Swagger JSON

Swashbuckle.AspNetCore automatycznie generuje plik Swagger JSON, który zawiera informacje o strukturze API, w tym szczegóły takie jak punkty końcowe, typy żądań i odpowiedzi oraz inne. Ten plik JSON może być używany przez inne narzędzia i usługi obsługujące standard Swagger/OpenAPI.

Plik JSON Swagger jest dostępny pod adresem "/swagger/v1/swagger.json" w bazowym adresie URL aplikacji API.

Swashbuckle ASP .NET Core (jak to działa dla programisty): Rysunek 2 – Plik JSON Swagger.

Adnotacje do kodu

Programiści mogą używać komentarzy i atrybutów XML w swoich kontrolerach .NET Core, aby dostarczyć dodatkowych informacji do dokumentacji Swagger. Obejmuje to opisy, przykłady i inne metadane, które wzbogacają wygenerowaną dokumentację 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

Opcje konfiguracji

Swashbuckle.AspNetCore oferuje różne opcje konfiguracyjne, które pozwalają dostosować sposób generowania dokumentacji Swagger. Programiści mogą kontrolować, które interfejsy API są dokumentowane, konfigurować konwencje nazewnictwa oraz dostosowywać inne ustawienia.

Oto niektóre z kluczowych opcji konfiguracyjnych oferowanych przez Swashbuckle.AspNetCore:

Opcje 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

Ta linia określa wersję dokumentu Swagger i zawiera metadane, takie jak tytuł i wersja API.

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

Ta opcja pozwala na dołączenie komentarzy XML z kodu w celu dostarczenia dodatkowych informacji w dokumentacji Swagger. Zmienna xmlPath powinna wskazywać lokalizację pliku komentarzy XML.

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

Ta opcja konfiguruje generator Swagger tak, aby używał camelCase dla nazw parametrów.

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

Można zarejestrować niestandardowe filtry operacji, aby modyfikować dokumentację Swagger dla określonych operacji. CustomOperationFilter to klasa, która implementuje IOperationFilter.

Opcje 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")
$vbLabelText   $csharpLabel

Ta linia konfiguruje Swagger UI do wyświetlania dokumentacji. Pierwszym parametrem jest adres URL pliku JSON Swagger, a drugim parametrem jest przyjazna dla użytkownika nazwa wersji API.

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

Możesz ustawić prefiks trasy dla interfejsu użytkownika Swagger. W tym przykładzie interfejs Swagger UI będzie dostępny pod adresem /swagger.

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

Ta opcja kontroluje sposób wyświetlania dokumentacji API w interfejsie Swagger UI. DocExpansion.None domyślnie zwija wszystkie operacje.

SwaggerOptions

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

Ta opcja określa, czy dokument Swagger ma być serializowany w formacie wersji 2.0 (true) czy 3.0 (false). Ustaw na true, jeśli chcesz korzystać ze Swagger 2.0.

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

Ta opcja wyświetla identyfikator operacji w interfejsie użytkownika Swagger, co może być przydatne podczas debugowania i zrozumienia struktury API.

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

Jeśli Twoje API korzysta z uwierzytelniania OAuth, możesz skonfigurować identyfikator klienta OAuth dla Swagger UI.

To tylko kilka przykładów dostępnych opcji konfiguracyjnych. Biblioteka Swashbuckle.AspNetCore jest wysoce konfigurowalna i można dostosować dokumentację Swagger do konkretnych potrzeb, łącząc różne opcje i filtry. Aby uzyskać najbardziej aktualne i wyczerpujące informacje na temat dostępnych opcji, należy zawsze korzystać z oficjalnej dokumentacji lub funkcji IntelliSense w swoim środowisku programistycznym.

Przedstawiamy IronPDF

Przegląd produktów IronPDF to biblioteka PDF w języku C# ze strony internetowej Iron Software, która pomaga odczytywać i generować dokumenty PDF. Może z łatwością konwertować sformatowane dokumenty zawierające informacje o stylach do formatu PDF. IronPDF pozwala bez trudu generować pliki PDF z treści HTML. Może pobierać treści HTML z adresu URL, a następnie generować pliki PDF.

IronPDF to świetne narzędzie do konwersji stron internetowych, adresów URL i kodu HTML na pliki PDF, które idealnie odzwierciedlają źródło. Idealnie nadaje się do generowania plików PDF z treści internetowych, takich jak raporty i faktury, oraz bez wysiłku tworzy wersje PDF dowolnej strony internetowej.

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

Instalacja

Zainstaluj IronPDF za pośrednictwem NuGet, korzystając z menedżera pakietów NuGet Package Manager Details lub konsoli menedżera pakietów Visual Studio Installation Guide.

W konsoli menedżera pakietów wpisz polecenie:

Install-Package IronPdf

Korzystanie z programu Visual Studio

Swashbuckle ASP .NET Core (Jak to działa dla programisty): Rysunek 3 — Otwórz swój projekt w Visual Studio. Przejdź do menu Narzędzia, wybierz Menedżer pakietów NuGet, a następnie wybierz Zarządzaj pakietami NuGet dla rozwiązania. W interfejsie menedżera pakietów NuGet wyszukaj pakiet IronPDF w zakładce Przeglądaj. Następnie wybierz i zainstaluj najnowszą wersję IronPDF.

Teraz zmodyfikujmy naszą aplikację, aby dodać funkcję pobierania treści stron internetowych jako plików 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

W tym przypadku wykorzystujemy dane pogodowe do wygenerowania ciągu znaków HTML, który następnie służy do utworzenia dokumentu PDF.

Treść HTML

Swashbuckle ASP .NET Core (Jak to działa dla programisty): Rysunek 4 – Treść HTML dla prognozy pogody.

A raport w formacie PDF wygląda następująco:

Swashbuckle ASP .NET Core (Jak to działa dla programisty): Rysunek 5 – Plik wyjściowy HTML do PDF: WeatherReport.pdf

Cały kod można znaleźć na GitHubie — Swashbuckle Demo Source Code.
Dokument zawiera niewielki znak wodny dotyczący licencji Trial, który można usunąć po uzyskaniu ważnej licencji.

Licencjonowanie (dostępna bezpłatna wersja próbna)

Aby powyższy kod działał, wymagany jest klucz licencyjny. Umieść ten klucz w pliku appsettings.json.

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

Licencja Trial jest dostępna dla programistów po zarejestrowaniu się w IronPDF Trial Registration. Do uzyskania licencji Trial nie jest wymagana karta kredytowa. Zarejestruj się, podając swój adres e-mail, aby uzyskać bezpłatną wersję próbną.

Wnioski

Zrozumienie działania Swashbuckle i IronPDF pozwala na skuteczne zintegrowanie dokumentacji API oraz funkcji generowania plików PDF z aplikacjami ASP.NET Core. IronPDF oferuje również obszerną dokumentację dotyczącą pierwszych kroków, a także różne przykłady kodu do generowania plików PDF.

Dodatkowo możesz zapoznać się z powiązanymi produktami Iron Software, które pomogą Ci rozwinąć umiejętności programistyczne i sprostać współczesnym wymaganiom aplikacji.

Często Zadawane Pytania

Jak mogę dokumentówać RESTful Web API przy użyciu Swashbuckle w ASP.NET Core?

Swashbuckle może służyć do dokumentówania RESTful Web API poprzez generowanie dokumentacji Swagger na podstawie komentarzy XML w kodzie. Należy zainstalować pakiet Swashbuckle.AspNetCore i skonfigurować go w pliku `Startup.cs` projektu .NET Core.

Jakie kroki należy wykonać, aby skonfigurować Swashbuckle dla nowego projektu ASP.NET Core Web API?

Aby skonfigurować Swashbuckle, zacznij od zainstalowania pakietu NuGet Swashbuckle.AspNetCore. Następnie skonfiguruj oprogramowanie pośredniczące Swagger w pliku `Startup.cs`, dodając `services.AddSwaggerGen()` w metodzie `ConfigureServices` oraz `app.UseSwagger()` wraz z `app.UseSwaggerUI()` w metodzie `Configure`.

Jak mogę przekonwertować zawartość HTML do formatu PDF w aplikacji .NET Core?

W aplikacji .NET Core można konwertować zawartość HTML do formatu PDF za pomocą biblioteki IronPDF. Biblioteka ta umożliwia konwersję ciągów znaków HTML, plików i adresów URL na dokumenty PDF przy użyciu metod takich jak `RenderHtmlAsPdf` i `RenderUrlAsPdf`.

Jakie są zalety korzystania z Swashbuckle podczas tworzenia interfejsów API?

Swashbuckle upraszcza dokumentację API poprzez automatyczne generowanie dokumentacji zgodnej ze standardem Swagger, co pomaga w utrzymaniu jasnych i spójnych standardów dokumentacji API. Zapewnia również przyjazny dla użytkownika interfejs do przeglądania i testowania interfejsów API za pośrednictwem Swagger UI.

Jak zintegrować funkcje generowania plików PDF w projekcie ASP.NET Core?

Integrację generowania plików PDF w projekcie ASP.NET Core można osiągnąć za pomocą IronPDF. Zainstaluj bibliotekę IronPDF za pośrednictwem NuGet i użyj jej metod do generowania plików PDF z różnych typów treści. Upewnij się, że projekt zawiera niezbędne dyrektywy using oraz wszelkie klucze licencyjne.

Jakie opcje konfiguracyjne są dostępne do dostosowywania dokumentacji Swagger w Swashbuckle?

Swashbuckle oferuje różne opcje konfiguracyjne umożliwiające dostosowanie dokumentacji Swagger, w tym ustawianie wersjonowania API, włączanie komentarzy XML, definiowanie konwencji nazewnictwa parametrów oraz dostosowywanie wyglądu i działania interfejsu użytkownika Swagger.

Jak mogę rozwiązać typowe problemy związane z używaniem Swashbuckle w projekcie .NET Core?

Typowe problemy związane z Swashbuckle można rozwiązać, upewniając się, że dokumentacja XML jest włączona we właściwościach projektu, sprawdzając poprawność wersji pakietów oraz weryfikując prawidłową konfigurację w pliku `Startup.cs`, w tym właściwą kolejność oprogramowania pośredniczącego.

Jakie są niektóre funkcje IronPDF do generowania plików PDF w języku C#?

IronPDF oferuje takie funkcje, jak konwersja treści HTML, adresów URL i ASP.NET do formatu PDF, dodawanie nagłówków i stopek, scalanie plików PDF oraz edycja istniejących plików PDF. Jest to kompleksowa biblioteka do obsługi operacji związanych z plikami PDF w projektach C#.

W jaki sposób IronPDF obsługuje licencjonowanie do użytku komercyjnego?

IronPDF obsługuje licencjonowanie za pomocą komercyjnego klucza licencyjnego. Możesz wypróbować IronPDF w ramach bezpłatnej wersji próbnej i dołączyć klucz licencyjny do konfiguracji projektu, zazwyczaj w pliku `appsettings.json`, w sekcji `IronPdf`.

Jacob Mellor, Dyrektor Technologiczny @ Team Iron
Dyrektor ds. technologii

Jacob Mellor jest Chief Technology Officer w Iron Software i wizjonerskim inżynierem, pionierem technologii C# PDF. Jako pierwotny deweloper głównej bazy kodowej Iron Software, kształtuje architekturę produktów firmy od jej początku, przekształcając ją wspólnie z CEO Cameron Rimington w firmę liczą...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie