Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
If you’ve been writing HTTP API’s, you likely have needed to return exceptions and errors back to the consuming clients. Before you go and grow your own solution to this common problem, there is RFC 7807 Problem Details for HTTP APIs which set out solve this problem.“problem detail” as a way to carry machine-readable details of errors in a HTTP response to avoid the need to define new error response formats for HTTP APIs.
Problem Details in ASP.NET Core
Now that you’re on board with Problem Details, how do we use or implement this in ASP.NET Core. Thankfully, Kristian Hellang has done all the heavy lifting and released Hellang.Middleware.ProblemDetails on NuGet.Been working on a combined exception and error status code handler middleware for https://t.co/A958XYy9Ej Core for a while. Decided to OSS it some time back. If you need something like this, you can find it here; https://t.co/c5QV4S2eIB.
— Kristian Hellang (@khellang) June 20, 2018
Hellang.Middleware.ProblemDetails
Once you get the NuGet package, it’s simply a matter of adding it to your Startup’sConfigure(IApplicationBuilder app)
:
By default with no configuration, this will return a Problem Details body and application/problem+json
content type for status codes returned from MVC. This means 404’s as well as status codes you return from your controller actions explicitly.
Here’s an example of the response for a 404 when a route is not found.
For making explicit returns such as UnauthorizedResult
:
This returns, as you might expect:
Bad Request
Most often you might be return aBadRequestObjectResult
when the users sends malformed request. In this case the solution is pretty sweet. Simply provide BadRequest()
with an object that is or derives from Microsoft.AspNetCore.Mvc.ProblemDetails
ProblemDetailsException
Another option is throw an exception. Specifically you can throw aProblemDetailsException
that takes a ProblemDetails
as a parameter.
Mapping Exceptions to ProblemDetails
Although I’m not in love with throwing aProblemDetailsException
, one of the reasons is you may not be directly inside an MVC Controller action. If you follow my blog enough, you know I like to decouple using something like the MediatR library. In this case you likely won’t be throwing a ProblemDetailsException
.
But no worries, this situation is covered by being able to map exceptions to ProblemDetailsExceptions
in the configuration.