This repository contains a bootstrapped ASP.NET 6 Web API solution.
Be sure to make the following changes once you clone the repository:
- Set the
<UserSecretsId>
property in/source/Api/Company.Product.WebApi.Api.csproj
to a unique GUID. - Set the
<UserSecretsId>
property in/source/Api/Company.Product.WebApi.ScheduledTasks.csproj
to a unique GUID. - Rename any occurrences of
Company
orProduct
in all file contents and filenames. - Carefully look through
/Directory.Build.props
for property values to change. Some values to change are:<RepositoryRootUrl>
<VersionPrefix>
<VersionSuffix>
<Company>
<Product>
<Authors>
<Copyright>
The solution is opinionated about several things. It's important to understand the purpose of each class before using the solution.
Things to do before running the applications:
-
Run the
set-postgresql-connection-strings.ps1
script. Here is the recommended PowerShell:.\scripts\dev\secrets\set-postgresql-connection-strings.ps1 -Environment DeveloperDocker -DatabaseHost postgresql -DatabaseName postgres -Verbose .\scripts\dev\secrets\set-postgresql-connection-strings.ps1 -Environment DeveloperVisualStudio -DatabaseHost localhost -DatabaseName postgres -Verbose
A common need is to wrap all responses in a response body envelope. This is simple enough within controller action methods but gets more challenging outside of controller contexts (e.g., validation filters and unhandled exception handlers). Additionally, Microsoft inexplicably does not implement IActionResult
for every HTTP status code.
I wrote a complete replacement for Microsoft's controller helper methods like Ok()
that I call results. With a simple fluent interface, you can construct an enveloped response. For action methods, use the ActionResult
class (see HealthController.cs
). For outside of controller contexts where you only have access to HttpContext
, use the HttpResult
class (see UnhandledExceptionHandler.cs
).
Swashbuckle has some annoying behavior that I was intent on fixing.
Swashbuckle does not correctly honor non-null reference types when the nullable reference type feature is enabled. The NullableSchemaFilter class corrects this behavior.
Swashbuckle does not render generic model type names correctly. The TitleFilter class corrects this behavior.
I wrote a couple of attributes that wrap common response types to reduce boilerplate.
The Scheduled Tasks console application can be used to execute jobs at certain times.
Seq is an excellent log sink. Both the Api
and ScheduledTasks
projects are configured to use Seq as a Serilog sink.
Framework or Library | Purpose |
---|---|
Entity Framework Core | Object-relational mapping |
Fluent Assertions | Test assertion |
Fluent Validation | Model validation |
Moq | Mocking |
NodaTime | Date/time |
Quartz.NET | Scheduling |
Serilog (console and Seq sinks) | Logging |
Swashbuckle | OpenAPI documentation |
TerraFX | Utilities |
xUnit | Test harness |
The application is versioned using a tweaked versioning scheme from .NET Arcade.
The solution supports debugging in either a console application or Docker.