Skip to content

Commit 043f160

Browse files
spboyerscottaddie
authored andcommitted
Update Get started with Swashbuckle to 3.0 (#13940)
* Update swagger example to 3.0, add sample code * edits and samples browser version * fix link to custom ui * address feedback * resolving feedback
1 parent d9b8885 commit 043f160

22 files changed

+842
-9
lines changed

Diff for: aspnetcore/tutorials/getting-started-with-swashbuckle.md

+64-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: zuckerthoben
44
description: Learn how to add Swashbuckle to your ASP.NET Core web API project to integrate the Swagger UI.
55
ms.author: scaddie
66
ms.custom: mvc
7-
ms.date: 06/21/2019
7+
ms.date: 08/21/2019
88
uid: tutorials/get-started-with-swashbuckle
99
---
1010
# Get started with Swashbuckle and ASP.NET Core
@@ -83,16 +83,32 @@ Add the Swagger generator to the services collection in the `Startup.ConfigureSe
8383

8484
::: moniker-end
8585

86-
::: moniker range=">= aspnetcore-2.1"
86+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
8787

8888
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=9-12)]
8989

9090
::: moniker-end
9191

92+
::: moniker range=">= aspnetcore-3.0"
93+
94+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_ConfigureServices&highlight=8-11)]
95+
96+
::: moniker-end
97+
9298
In the `Startup.Configure` method, enable the middleware for serving the generated JSON document and the Swagger UI:
9399

100+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
101+
94102
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_Configure&highlight=4,8-11)]
95103

104+
::: moniker-end
105+
106+
::: moniker range=">= aspnetcore-3.0"
107+
108+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_Configure&highlight=4,8-11)]
109+
110+
::: moniker-end
111+
96112
The preceding `UseSwaggerUI` method call enables the [Static File Middleware](xref:fundamentals/static-files). If targeting .NET Framework or .NET Core 1.x, add the [Microsoft.AspNetCore.StaticFiles](https://www.nuget.org/packages/Microsoft.AspNetCore.StaticFiles/) NuGet package to the project.
97113

98114
Launch the app, and navigate to `http://localhost:<port>/swagger/v1/swagger.json`. The generated document describing the endpoints appears as shown in [Swagger specification (swagger.json)](xref:tutorials/web-api-help-pages-using-swagger#swagger-specification-swaggerjson).
@@ -110,8 +126,13 @@ If using directories with IIS or a reverse proxy, set the Swagger endpoint to a
110126

111127
Swagger provides options for documenting the object model and customizing the UI to match your theme.
112128

113-
In the Startup class, add the following namespaces:
114-
[!code-csharp[](~/tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup2.cs?name=snippet_PreReqNamespaces)]
129+
In the `Startup` class, add the following namespaces:
130+
131+
```csharp
132+
using System;
133+
using System.Reflection;
134+
using System.IO;
135+
```
115136

116137
### API info and description
117138

@@ -239,7 +260,13 @@ namespace TodoApi
239260

240261
Configure Swagger to use the XML file that's generated with the preceding instructions. For Linux or non-Windows operating systems, file names and paths can be case-sensitive. For example, a *TodoApi.XML* file is valid on Windows but not CentOS.
241262

242-
::: moniker range=">= aspnetcore-2.1"
263+
::: moniker range=">= aspnetcore-3.0"
264+
265+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup.cs?name=snippet_ConfigureServices&highlight=30-32)]
266+
267+
::: moniker-end
268+
269+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
243270

244271
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup.cs?name=snippet_ConfigureServices&highlight=31-33)]
245272

@@ -304,12 +331,18 @@ Add a [\<remarks>](/dotnet/csharp/programming-guide/xmldoc/remarks) element to t
304331

305332
::: moniker-end
306333

307-
::: moniker range=">= aspnetcore-2.1"
334+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
308335

309336
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_Create&highlight=4-14)]
310337

311338
::: moniker-end
312339

340+
::: moniker range=">= aspnetcore-3.0"
341+
342+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_Create&highlight=4-14)]
343+
344+
::: moniker-end
345+
313346
Notice the UI enhancements with these additional comments:
314347

315348
![Swagger UI with additional comments shown](web-api-help-pages-using-swagger/_static/xml-comments-extended.png)
@@ -356,12 +389,18 @@ Add the `[Produces("application/json")]` attribute to the API controller. Its pu
356389

357390
::: moniker-end
358391

359-
::: moniker range=">= aspnetcore-2.1"
392+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
360393

361394
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_TodoController&highlight=1)]
362395

363396
::: moniker-end
364397

398+
::: moniker range=">= aspnetcore-3.0"
399+
400+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_TodoController&highlight=1)]
401+
402+
::: moniker-end
403+
365404
The **Response Content Type** drop-down selects this content type as the default for the controller's GET actions:
366405

367406
![Swagger UI with default response content type](web-api-help-pages-using-swagger/_static/json-response-content-type.png)
@@ -380,12 +419,18 @@ The `Create` action returns an HTTP 201 status code on success. An HTTP 400 stat
380419

381420
::: moniker-end
382421

383-
::: moniker range=">= aspnetcore-2.1"
422+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
384423

385424
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_Create&highlight=17,18,20,21)]
386425

387426
::: moniker-end
388427

428+
::: moniker range=">= aspnetcore-3.0"
429+
430+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Controllers/TodoController.cs?name=snippet_Create&highlight=17,18,20,21)]
431+
432+
::: moniker-end
433+
389434
The Swagger UI now clearly documents the expected HTTP response codes:
390435

391436
![Swagger UI showing POST Response Class description 'Returns the newly created Todo item' and '400 - If the item is null' for status code and reason under Response Messages](web-api-help-pages-using-swagger/_static/data-annotations-response-types.png)
@@ -410,7 +455,17 @@ The preceding NuGet package is already installed if targeting .NET Core 2.x and
410455

411456
Enable Static File Middleware:
412457

413-
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.0/TodoApi.Swashbuckle/Startup.cs?name=snippet_Configure&highlight=3)]
458+
::: moniker range=">= aspnetcore-2.1 <= aspnetcore-2.2"
459+
460+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/2.1/TodoApi.Swashbuckle/Startup.cs?name=snippet_Configure&highlight=3)]
461+
462+
::: moniker-end
463+
464+
::: moniker range=">= aspnetcore-3.0"
465+
466+
[!code-csharp[](../tutorials/web-api-help-pages-using-swagger/samples/3.0/TodoApi.Swashbuckle/Startup.cs?name=snippet_Configure&highlight=3)]
467+
468+
::: moniker-end
414469

415470
Acquire the contents of the *dist* folder from the [Swagger UI GitHub repository](https://github.com/swagger-api/swagger-ui/tree/master/dist). This folder contains the necessary assets for the Swagger UI page.
416471

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using TodoApi.Models;
5+
6+
namespace TodoApi.Controllers
7+
{
8+
#region snippet_TodoController
9+
[Produces("application/json")]
10+
[Route("api/[controller]")]
11+
[ApiController]
12+
public class TodoController : ControllerBase
13+
{
14+
private readonly TodoContext _context;
15+
#endregion
16+
17+
public TodoController(TodoContext context)
18+
{
19+
_context = context;
20+
21+
if (_context.TodoItems.Count() == 0)
22+
{
23+
_context.TodoItems.Add(new TodoItem { Name = "Item1" });
24+
_context.SaveChanges();
25+
}
26+
}
27+
28+
#region snippet_GetAll
29+
[HttpGet]
30+
public ActionResult<List<TodoItem>> GetAll()
31+
{
32+
return _context.TodoItems.ToList();
33+
}
34+
#endregion
35+
36+
#region snippet_GetById
37+
[HttpGet("{id}", Name = "GetTodo")]
38+
public ActionResult<TodoItem> GetById(long id)
39+
{
40+
var item = _context.TodoItems.Find(id);
41+
42+
if (item == null)
43+
{
44+
return NotFound();
45+
}
46+
47+
return item;
48+
}
49+
#endregion
50+
51+
#region snippet_Create
52+
/// <summary>
53+
/// Creates a TodoItem.
54+
/// </summary>
55+
/// <remarks>
56+
/// Sample request:
57+
///
58+
/// POST /Todo
59+
/// {
60+
/// "id": 1,
61+
/// "name": "Item1",
62+
/// "isComplete": true
63+
/// }
64+
///
65+
/// </remarks>
66+
/// <param name="item"></param>
67+
/// <returns>A newly created TodoItem</returns>
68+
/// <response code="201">Returns the newly created item</response>
69+
/// <response code="400">If the item is null</response>
70+
[HttpPost]
71+
[ProducesResponseType(201)]
72+
[ProducesResponseType(400)]
73+
public ActionResult<TodoItem> Create(TodoItem item)
74+
{
75+
_context.TodoItems.Add(item);
76+
_context.SaveChanges();
77+
78+
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
79+
}
80+
#endregion
81+
82+
#region snippet_Update
83+
[HttpPut("{id}")]
84+
public IActionResult Update(long id, TodoItem item)
85+
{
86+
if (item == null || item.Id != id)
87+
{
88+
return BadRequest();
89+
}
90+
91+
var todo = _context.TodoItems.Find(id);
92+
93+
if (todo == null)
94+
{
95+
return NotFound();
96+
}
97+
98+
todo.IsComplete = item.IsComplete;
99+
todo.Name = item.Name;
100+
101+
_context.TodoItems.Update(todo);
102+
_context.SaveChanges();
103+
104+
return NoContent();
105+
}
106+
#endregion
107+
108+
#region snippet_Delete
109+
/// <summary>
110+
/// Deletes a specific TodoItem.
111+
/// </summary>
112+
/// <param name="id"></param>
113+
[HttpDelete("{id}")]
114+
public IActionResult Delete(long id)
115+
{
116+
var todo = _context.TodoItems.Find(id);
117+
118+
if (todo == null)
119+
{
120+
return NotFound();
121+
}
122+
123+
_context.TodoItems.Remove(todo);
124+
_context.SaveChanges();
125+
126+
return NoContent();
127+
}
128+
#endregion
129+
}
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace TodoApi.Models
4+
{
5+
public class TodoContext : DbContext
6+
{
7+
public TodoContext(DbContextOptions<TodoContext> options)
8+
: base(options)
9+
{
10+
}
11+
12+
public DbSet<TodoItem> TodoItems { get; set; }
13+
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.ComponentModel;
2+
using System.ComponentModel.DataAnnotations;
3+
4+
namespace TodoApi.Models
5+
{
6+
public class TodoItem
7+
{
8+
public long Id { get; set; }
9+
10+
[Required]
11+
public string Name { get; set; }
12+
13+
[DefaultValue(false)]
14+
public bool IsComplete { get; set; }
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Hosting;
3+
4+
namespace TodoApi
5+
{
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
CreateHostBuilder(args).Build().Run();
11+
}
12+
13+
public static IHostBuilder CreateHostBuilder(string[] args) =>
14+
Host.CreateDefaultBuilder(args)
15+
.ConfigureWebHostDefaults(webBuilder =>
16+
{
17+
webBuilder.UseStartup<Startup>();
18+
});
19+
}
20+
}

0 commit comments

Comments
 (0)