Skip to content

Commit 5d5d4f1

Browse files
committed
feat: Add Swagger and some initial examples of using of it
1 parent 08eca89 commit 5d5d4f1

8 files changed

Lines changed: 117 additions & 12 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Swashbuckle.AspNetCore.Swagger;
3+
using System;
4+
using System.IO;
5+
using System.Reflection;
6+
7+
namespace ReferenceProject
8+
{
9+
public static class DependenciesConfig
10+
{
11+
public static IServiceCollection AddSwagger(this IServiceCollection services)
12+
{
13+
// Register the Swagger generator, defining 1 or more Swagger documents
14+
services.AddSwaggerGen(c =>
15+
{
16+
c.SwaggerDoc(Constants.Swagger.Version, new Info { Title = Constants.Swagger.ApiName, Version = Constants.Swagger.Version });
17+
18+
// Set the comments path for the Swagger JSON and UI.
19+
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
20+
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
21+
c.IncludeXmlComments(xmlPath);
22+
});
23+
24+
return services;
25+
}
26+
}
27+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Microsoft.AspNetCore.Builder;
2+
3+
namespace ReferenceProject
4+
{
5+
public static class MiddlewareConfig
6+
{
7+
public static IApplicationBuilder UseSwaggerWithOptions(this IApplicationBuilder app)
8+
{
9+
// Enable middleware to serve generated Swagger as a JSON endpoint.
10+
SwaggerBuilderExtensions.UseSwagger(app);
11+
12+
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
13+
// specifying the Swagger JSON endpoint.
14+
app.UseSwaggerUI(c =>
15+
{
16+
// Uncomment this line if you want to access the Swagger UI as http://localhost:5000
17+
// c.RoutePrefix = string.Empty;
18+
c.SwaggerEndpoint(Constants.Swagger.EndPoint, Constants.Swagger.ApiName);
19+
});
20+
21+
return app;
22+
}
23+
}
24+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace ReferenceProject
2+
{
3+
public static class Constants
4+
{
5+
public static class Swagger
6+
{
7+
public static string EndPoint => $"/swagger/{Version}/swagger.json";
8+
public static string ApiName => "My API";
9+
public static string Version => "v1";
10+
}
11+
}
12+
}

ProjectTemplates/AspNetCore.WebApi/ReferenceProject/ReferenceProject/Controllers/ProductsController.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using AutoMapper;
2+
using Microsoft.AspNetCore.Http;
23
using Microsoft.AspNetCore.Mvc;
4+
using Microsoft.AspNetCore.Mvc.Formatters;
35
using ReferenceProject.Repo;
46
using System;
57
using System.Collections.Generic;
@@ -9,6 +11,7 @@ namespace ReferenceProject.Controllers
911
{
1012
[Route("[controller]")]
1113
[ApiController]
14+
[Produces("application/json")]
1215
public class ProductsController: ControllerBase
1316
{
1417
Repo.IProductsRepo ProductsRepo { get; }
@@ -20,21 +23,34 @@ public ProductsController(Repo.IProductsRepo productsRepo, IMapper mapper)
2023
ProductsRepo = productsRepo ?? throw new ArgumentNullException(nameof(productsRepo));
2124
}
2225

26+
/// <summary>
27+
/// Get all products
28+
/// </summary>
29+
/// <response code="200">List of all of the products</response>
2330
[HttpGet]
2431
public IEnumerable<Dto.Product> Get()
2532
{
2633
return ProductsRepo.Get().Select(Mapper.Map<Dto.Product>);
2734
}
2835

36+
/// <summary>
37+
/// Get product by id
38+
/// </summary>
39+
/// <param name="id">Product id</param>
40+
/// <response code="200">Product with the specified id</response>
41+
[ProducesResponseType(StatusCodes.Status404NotFound)]
2942
[HttpGet]
3043
[Route("{id}")]
3144
public Dto.Product GetById(int id)
3245
{
3346
return Mapper.Map<Dto.Product>(ProductsRepo.GetById(id));
3447
}
3548

49+
/// <summary>
50+
/// Example of an exception handling
51+
/// </summary>
3652
[HttpGet("ThrowAnException")]
37-
public void ThrowAnException()
53+
public IActionResult ThrowAnException()
3854
{
3955
throw new Exception("Example exception");
4056
}

ProjectTemplates/AspNetCore.WebApi/ReferenceProject/ReferenceProject/Controllers/ValuesController.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,35 @@ namespace ReferenceProject.Controllers
55
{
66
#pragma warning disable RECS0154 // Parameter is never used
77

8+
/// <summary>
9+
/// Standart ASP.Net Core Example Controller
10+
/// </summary>
811
[Route("[controller]")]
912
[ApiController]
13+
[Produces("application/json")]
1014
public class ValuesController : ControllerBase
1115
{
12-
// GET values
16+
/// <summary>
17+
/// Get values
18+
/// </summary>
19+
/// <response code="200">List of values</response>
1320
[HttpGet]
14-
public ActionResult<IEnumerable<string>> Get()
21+
public IEnumerable<string> Get()
1522
{
1623
return new string[] { "value1", "value2" };
1724
}
1825

1926
// GET values/5
2027
[HttpGet("{id}")]
21-
public ActionResult<string> Get(int id)
28+
public string Get(int id)
2229
{
2330
return "value";
2431
}
2532

26-
// POST values
33+
/// <summary>
34+
/// Add new value
35+
/// </summary>
36+
/// <param name="value">New value</param>
2737
[HttpPost]
2838
public void Post([FromBody] string value)
2939
{
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
namespace ReferenceProject.Dto
22
{
3+
/// <summary>
4+
/// Model example: Product
5+
/// </summary>
36
public class Product
47
{
8+
/// <summary>
9+
/// Product name
10+
/// </summary>
511
public string Name { get; set; }
612
}
713
}

ProjectTemplates/AspNetCore.WebApi/ReferenceProject/ReferenceProject/ReferenceProject.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
88
<DefineConstants>DEBUG;TRACE</DefineConstants>
9+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
10+
<WarningsAsErrors>NU1605</WarningsAsErrors>
11+
<NoWarn>1701;1702;1591</NoWarn>
912
</PropertyGroup>
1013

1114
<ItemGroup>
@@ -25,6 +28,8 @@
2528
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
2629
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
2730
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
31+
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
32+
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" />
2833
<PackageReference Include="System.Net.Http" Version="4.3.4" />
2934
</ItemGroup>
3035

ProjectTemplates/AspNetCore.WebApi/ReferenceProject/ReferenceProject/Startup.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.IO;
2-
using Autofac;
1+
using Autofac;
32
using Autofac.Configuration;
43
using AutoMapper;
54
using Microsoft.AspNetCore.Builder;
@@ -15,6 +14,7 @@
1514
using Newtonsoft.Json.Serialization;
1615
using ReferenceProject.Filters;
1716
using ReferenceProject.Modules;
17+
using System.IO;
1818

1919
// TODO: Create and validate configuration in web.config:
2020
// https://www.talkingdotnet.com/how-to-increase-file-upload-size-asp-net-core/
@@ -37,7 +37,7 @@ public Startup(IConfiguration configuration, IHostingEnvironment env, ILogger<St
3737
DotNetEnv.Env.Load();
3838
}
3939

40-
JsonConvert.DefaultSettings = () =>
40+
JsonConvert.DefaultSettings = () =>
4141
new JsonSerializerSettings()
4242
{
4343
ContractResolver = new CamelCasePropertyNamesContractResolver(),
@@ -49,7 +49,7 @@ public Startup(IConfiguration configuration, IHostingEnvironment env, ILogger<St
4949
#else
5050
Formatting = Formatting.None
5151
#endif
52-
};
52+
};
5353
}
5454

5555
public IConfiguration Configuration { get; }
@@ -71,6 +71,8 @@ public void ConfigureServices(IServiceCollection services)
7171
options.Filters.Add(new ValidateModelFilter());
7272
options.Filters.Add(new CacheControlFilter());
7373
})
74+
.AddApiExplorer()
75+
.AddJsonFormatters()
7476
.AddJsonOptions(options =>
7577
{
7678
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
@@ -85,7 +87,9 @@ public void ConfigureServices(IServiceCollection services)
8587
})
8688
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
8789

88-
services.AddAutoMapper();
90+
services
91+
.AddAutoMapper()
92+
.AddSwagger();
8993
}
9094

9195
// ConfigureContainer is where you can register things directly
@@ -122,8 +126,9 @@ public void Configure(IApplicationBuilder app/*, IHostingEnvironment env*/)
122126
.AllowAnyHeader()
123127
.AllowCredentials());
124128

125-
// Options verb handler must be added after CORS
126-
app.UseOptionsVerbHandler();
129+
app
130+
.UseOptionsVerbHandler() // Options verb handler must be added after CORS
131+
.UseSwaggerWithOptions();
127132

128133
app.UseMvcWithDefaultRoute();
129134

0 commit comments

Comments
 (0)