« Swashbuckle » : différence entre les versions
Apparence
Ligne 156 : | Ligne 156 : | ||
[ProducesResponseType(typeof(IEnumerable<Item>), StatusCodes.Status200OK)] | [ProducesResponseType(typeof(IEnumerable<Item>), StatusCodes.Status200OK)] | ||
public IActionResult Get() { /* ... */ } | public IActionResult Get() { /* ... */ } | ||
</filebox> | |||
== [https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-5.0&tabs=visual-studio-code#customize-the-ui Dark theme] == | |||
<filebox fn='Startup.cs'> | |||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |||
{ | |||
if (env.IsDevelopment()) | |||
{ | |||
app.UseDeveloperExceptionPage(); | |||
app.UseStaticFiles(); | |||
app.UseSwagger(); | |||
app.UseSwaggerUI(c => | |||
{ | |||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "EFWebApi v1"); | |||
c.RoutePrefix = string.Empty; | |||
c.InjectStylesheet("/swagger-ui/dark-theme.css"); | |||
}); | |||
} | |||
</filebox> | |||
<filebox fn='wwwroot/swagger-ui/dark-theme.css' collapsed> | |||
.swagger-ui .topbar .download-url-wrapper .select-label select { | |||
border: 2px solid #89bf04;; | |||
} | |||
body { | |||
background-color: #303030; | |||
} | |||
.swagger-ui, | |||
.swagger-ui .info .title, | |||
.swagger-ui .opblock-tag, | |||
.swagger-ui section.models h4, | |||
.swagger-ui .opblock .opblock-summary-operation-id, | |||
.swagger-ui .opblock .opblock-summary-path, | |||
.swagger-ui .opblock .opblock-summary-path__deprecated, | |||
.swagger-ui table thead tr td, | |||
.swagger-ui table thead tr th, | |||
.swagger-ui .parameter__name, | |||
.swagger-ui .parameter__type, | |||
.swagger-ui .response-col_status, | |||
.swagger-ui .model-title, | |||
.swagger-ui .model, | |||
.swagger-ui .tab li { | |||
color: #f0f0f0; | |||
} | |||
.swagger-ui input[type="email"], | |||
.swagger-ui input[type="file"], | |||
.swagger-ui input[type="password"], | |||
.swagger-ui input[type="search"], | |||
.swagger-ui input[type="text"], | |||
.swagger-ui textarea { | |||
background: #303030; | |||
color: #f0f0f0; | |||
border: 1px solid gray; | |||
} | |||
.swagger-ui .opblock .opblock-section-header { | |||
background-color: #1b1b1b; | |||
} | |||
.swagger-ui .opblock .opblock-section-header h4, | |||
.swagger-ui .btn { | |||
color: #f0f0f0; | |||
} | |||
.swagger-ui input[disabled], .swagger-ui select[disabled], .swagger-ui textarea[disabled] { | |||
background-color: #303030; | |||
color: lightgray; | |||
} | |||
.swagger-ui select { | |||
background: #303030 url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="gray"><path d="M13.418 7.859a.695.695 0 01.978 0 .68.68 0 010 .969l-3.908 3.83a.697.697 0 01-.979 0l-3.908-3.83a.68.68 0 010-.969.695.695 0 01.978 0L10 11l3.418-3.141z"/></svg>') right 10px center no-repeat; | |||
color: #f0f0f0; | |||
} | |||
.swagger-ui .response-control-media-type--accept-controller select { | |||
border-color: #89bf04; | |||
} | |||
.swagger-ui .response-control-media-type__accept-message { | |||
color: #89bf04; | |||
} | |||
.arrow path { | |||
fill: gray; | |||
} | |||
.swagger-ui section.models .model-container { | |||
border: 1px solid #61affe; | |||
} | |||
.swagger-ui .model-toggle::after { | |||
background: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="gray"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>') 50% no-repeat; | |||
} | |||
.swagger-ui .download-contents { | |||
width: unset; | |||
} | |||
</filebox> | </filebox> | ||
Version du 20 juin 2021 à 22:41
Liens
NSwag
Installation
# pour vscode
dotnet add package NSwag.AspNetCore
# Add to the project file *.csproj:
# <ItemGroup>
# <PackageReference Include="NSwag.AspNetCore" Version="11.17.15" />
|
Configuration
Configuration Web API
Startup.cs |
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerDocument();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOpenApi();
app.UseSwaggerUi3();
|
Configuration MVC
Startup.cs |
using NJsonSchema;
using NSwag.AspNetCore;
using System.Reflection;
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
// à ajouter avant app.UseSpa
app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, settings =>
{
settings.GeneratorSettings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase;
settings.PostProcess = document =>
{
//document.Info.Version = "v1";
document.Info.Title = "Test API";
document.Info.Description = "A simple ASP.NET Core web API";
//document.Info.TermsOfService = "None";
document.Info.Contact = new NSwag.SwaggerContact
{
Name = "Nicolas",
//Email = string.Empty,
//Url = "https://twitter.com/spboyer"
};
/*document.Info.License = new NSwag.SwaggerLicense
{
Name = "Use under LICX",
Url = "https://example.com/license"
};*/
};
});
|
Problème avec IActionResult
NSwag utilise la réflexion pour obtenir le type de retour. Avec IActionResult il ne peut pas.
[HttpGet]
// utiliser SwaggerResponse
[SwaggerResponse(HttpStatusCode.OK, typeof(IReadOnlyList<ItemDto>))]
[SwaggerResponse(HttpStatusCode.BadRequest, typeof(void))]
// ou ProducesResponseType
[ProducesResponseType(typeof(IReadOnlyList<ItemDto>), StatusCodes.Status200OK)]
public IActionResult Get()
|
Swashbuckle
Installation
dotnet add package Swashbuckle.AspNetCore |
Startup.cs |
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "EFWebApi", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "EFWebApi v1");
c.RoutePrefix = string.Empty; // serve the Swagger UI at the app's root (http://localhost:<port>/)
});
}
|
Usage
Controllers/ItemController.cs |
[ApiController]
[Produces("application/json")] // set the Media type
[Route("[controller]")]
public class ItemController : ControllerBase
{
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<Item>), StatusCodes.Status200OK)] // set the status code and the return type
public IActionResult Get() { /* ... */ }
}
|
XML documentation
MyProject.csproj |
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
|
Startup.cs |
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "EFWebApi", Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
|
Controllers/ItemController.cs |
/// <summary>
/// Get the items.
/// </summary>
/// <remarks>
/// Sample request:
///
/// GET /item
///
/// </remarks>
/// <returns>The items</returns>
/// <response code="200">Returns the items</response>
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<Item>), StatusCodes.Status200OK)]
public IActionResult Get() { /* ... */ }
|
Dark theme
Startup.cs |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "EFWebApi v1");
c.RoutePrefix = string.Empty;
c.InjectStylesheet("/swagger-ui/dark-theme.css");
});
}
|
wwwroot/swagger-ui/dark-theme.css |
.swagger-ui .topbar .download-url-wrapper .select-label select {
border: 2px solid #89bf04;;
}
body {
background-color: #303030;
}
.swagger-ui,
.swagger-ui .info .title,
.swagger-ui .opblock-tag,
.swagger-ui section.models h4,
.swagger-ui .opblock .opblock-summary-operation-id,
.swagger-ui .opblock .opblock-summary-path,
.swagger-ui .opblock .opblock-summary-path__deprecated,
.swagger-ui table thead tr td,
.swagger-ui table thead tr th,
.swagger-ui .parameter__name,
.swagger-ui .parameter__type,
.swagger-ui .response-col_status,
.swagger-ui .model-title,
.swagger-ui .model,
.swagger-ui .tab li {
color: #f0f0f0;
}
.swagger-ui input[type="email"],
.swagger-ui input[type="file"],
.swagger-ui input[type="password"],
.swagger-ui input[type="search"],
.swagger-ui input[type="text"],
.swagger-ui textarea {
background: #303030;
color: #f0f0f0;
border: 1px solid gray;
}
.swagger-ui .opblock .opblock-section-header {
background-color: #1b1b1b;
}
.swagger-ui .opblock .opblock-section-header h4,
.swagger-ui .btn {
color: #f0f0f0;
}
.swagger-ui input[disabled], .swagger-ui select[disabled], .swagger-ui textarea[disabled] {
background-color: #303030;
color: lightgray;
}
.swagger-ui select {
background: #303030 url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="gray"><path d="M13.418 7.859a.695.695 0 01.978 0 .68.68 0 010 .969l-3.908 3.83a.697.697 0 01-.979 0l-3.908-3.83a.68.68 0 010-.969.695.695 0 01.978 0L10 11l3.418-3.141z"/></svg>') right 10px center no-repeat;
color: #f0f0f0;
}
.swagger-ui .response-control-media-type--accept-controller select {
border-color: #89bf04;
}
.swagger-ui .response-control-media-type__accept-message {
color: #89bf04;
}
.arrow path {
fill: gray;
}
.swagger-ui section.models .model-container {
border: 1px solid #61affe;
}
.swagger-ui .model-toggle::after {
background: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="gray"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>') 50% no-repeat;
}
.swagger-ui .download-contents {
width: unset;
}
|
Url
Url | Resource |
---|---|
http://localhost:<port>/swagger | swagger UI |
http://localhost:<port>/swagger/v1/swagger.json | swagger json |
Dans un projet Web API avec Visual Studio Code, ouvrir le navigateur sur la page swagger.
.vscode\launch.json |
{
"configurations": [
{
"serverReadyAction": {
"action": "openExternally",
"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)",
"uriFormat": "%s/swagger"
},
// autre solution
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}/swagger/index.html?url=/swagger/v1/swagger.json#!/Items"
}
}
|
Paramètres optionnels
Swagger ne gère pas les paramètres optionnels s'ils font partie du chemin, il les considère comme des paramètres required.