Taking a look at the Problem Details enhancements in ASP.NET 9
Problem Details in ASP.NET link
Last year, I wrote about the new IExceptionHandler
middleware introduced in ASP.NET 8.
In the post Translating Exceptions into Problem Details Responses, I showed how to leverage the middleware to turn exceptions into Problem Details responses.
In ASP.NET 9, the exception handler middleware has been enhanced to provide more flexibility and control over the response status code when using Problem Details.
To recap, Problem Details is becoming a standardized way (RFC) to represent error information within the response of an HTTP API. The definition given to a "problem detail" in the RFC goes as follows, to carry machine-readable details of errors in HTTP response content to avoid the need to define new error response formats for HTTP APIs.
ASP.NET already supports Problem Details, but you have to opt into it. This can quickly be done by registering the Problem Details middleware within the request pipeline with 2 lines of code, and an additional line to also handle thrown exceptions during the execution of the endpoint.
Using AddProblemDetails
in combination with UseStatusCodePages
is enough to start returning Problem Details responses for endpoints that return an empty non-successful response (e.g. a BadRequest
).
Keep in mind that if the endpoint returns a non-successful response with a body, the provided body will be used instead (see examples).
But, as you can see in the above example, the UseExceptionHandler
method is also included.
This will translate exceptions, which are thrown during the execution of the endpoint, into response bodies that are compliant with the Problem Details format.
Otherwise, when the exception middleware is not included, the API will simply return a generic 500
response without a body.
Using the setup shown in the snippet, the following response is returned when an endpoint throws an exception.
This shows the standard behavior.
In Translating Exceptions into Problem Details Responses I've demonstrated how to customize the Problem Details by implementing an exception handler the IExceptionHandler
interface.
This allowed us to provide more information to the caller using the information of an exception, include extra information using extension members, and to change the default 500
status code of the response.
New: StatusCodeSelector
link
With the new addition in ASP.NET 9, we can simplify this by using the new StatusCodeSelector
configuration property.
This addition makes a custom implementation of an exception handler almost unnecessary (for most cases). You could use this for more complex scenarios, or to log the exception. For the latter, you should really be using OpenTelemetry instead.
Using the StatusCodeSelector
is very handy to quickly change the default status code of 500
based on the exception.
In the following example, the status code is decided based on the exception's type:
Resulting in the following result when a UserNotFoundException
exception is thrown by the application.
Using the StatusCodeSelector
in combination with an Exception Handler
link
When you decide to implement a custom exception handler, you can still use the StatusCodeSelector
property to set the status code.
Important to know is that if the StatusCode
is set by the exception handler, the StatusCodeSelector
is ignored.
Conclusion link
In this post, we've seen how the new StatusCodeSelector
property allows us to quickly adapt the default status code of 500
based on the exception type.
Because the StatusCodeSelector
retrieves the exception, other properties of the exception can also be used to determine the status code.
Examples link
Let's take a look at examples of different ASP.NET endpoints, and how they translate into Problem Details responses.
Outgoing links
Feel free to update this blog post on GitHub, thanks in advance!
Join My Newsletter (WIP)
Join my weekly newsletter to receive my latest blog posts and bits, directly in your inbox.
Support me
I appreciate it if you would support me if have you enjoyed this post and found it useful, thank you in advance.