DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult
2024.0.14.6-preview-1860304
See the version list below for details.
dotnet add package DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult --version 2024.0.14.6-preview-1860304
NuGet\Install-Package DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult -Version 2024.0.14.6-preview-1860304
<PackageReference Include="DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult" Version="2024.0.14.6-preview-1860304" />
paket add DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult --version 2024.0.14.6-preview-1860304
#r "nuget: DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult, 2024.0.14.6-preview-1860304"
// Install DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult as a Cake Addin #addin nuget:?package=DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult&version=2024.0.14.6-preview-1860304&prerelease // Install DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult as a Cake Tool #tool nuget:?package=DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult&version=2024.0.14.6-preview-1860304&prerelease
ASP.NET Core WebApp Self-Documented Problem Result Extension
© 2024 DotNet Brightener
Introduction
Have you ever wanted to have a consistent way of returning errors from your ASP.NET Core Web application? This package provides an abstraction for responding errors from your application to the client, base on the RFC 9457 specification.
When the application encounter an error, it should return a ProblemDetails
object that contains information about the error.
This package
Added a global exception handler to catch unhandled exceptions and return a
ProblemDetails
object. AnILogger
is also added to log the exception automatically for the unhandled exceptions.Provides a based
IProblembResult
interface and its extension methodsToProblemDetails()
orToProblemResult()
, to create consistent error responses. The error response format is based on the RFC 9457 specification.
When your application needs to response the error, you can either throw an exception derived from BaseProblemDetailsError
class or simply create a class that implements IProblemResult
interface. The error object will be converted to ProblemDetails
object and returned to the client. Check Usage section for more information.
Installation
You can install the package from NuGet:
dotnet add package DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult
Usage
1. Enable the global exception handler
Add the following code to your Startup.cs
(if you use Startup.cs) or Program.cs
(by default) file:
// this can be omitted if your application already added IHttpContextAccessor
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// The default way of handling unhandled exceptions
builder.Services.AddExceptionHandler<UnhandledExceptionResponseHandler>();
// Adds services required for creation of <see cref="ProblemDetails"/> for failed requests.
builder.Services.AddProblemDetails();
// Add the following to your Configure method,
// or after
// var app = builder.Build(); if you use Program.cs
app.UseExceptionHandler();
After the configuration above, if your application throws an exception, the response will be a ProblemDetails
object.
2. Create a consistent error response
2.1. Using Exception approach
Traditionally we used to throw exceptions when there are errors. You can create an exception class that inherits BaseProblemDetailsError
class. The <summary>
and <remarks>
XML comments will be used to generate the ProblemDetails
object.
/// <summary>
/// The error represents the requested object of type `User` could not be found
/// </summary>
/// <remarks>
/// The error is thrown because the requested resource of type `User` could not be found
/// </remarks>
public class UserNotFoundException : BaseProblemDetailsError
{
public UserNotFoundException()
: base("User Not Found", HttpStatusCode.BadRequest)
{
}
public UserNotFoundException(long userId)
: this()
{
Data.Add("userId", userId);
}
}
Somewhere in your application, where an error is expected, you can throw the exception as followed:
// UserService.cs
public User GetUser(long userId)
{
var user = _userRepository.GetUser(userId);
if (user == null)
{
throw new UserNotFoundException(userId);
}
return user;
}
Without having to handle the exception, the error will be caught by the global exception handler and return a ProblemDetails
object.
// UserController.cs
[HttpGet("{userId}")]
public IActionResult GetUserDetail(long userId)
{
var user = _userService.GetUser(userId);
// Without handling the exception, the error will be caught by the global exception handler
return Ok(user);
}
2.2. Using ProblemResult approach
Create a class that inherits BaseProblemDetailsError
. The <summary>
and <remarks>
XML comments will be used to generate the ProblemDetails
object.
using AspNet.Extensions.SelfDocumentedProblemResult.ErrorResults;
/// <summary>
/// The error represents the requested object of type `User` could not be found
/// </summary>
/// <remarks>
/// The error is thrown because the requested resource of type `User` could not be found
/// </remarks>
public class UserNotFoundError : BaseProblemDetailsError
{
public UserNotFoundError()
: base(HttpStatusCode.NotFound)
{
}
public UserNotFoundError(long userId)
: this()
{
Data.Add("userId", userId);
}
}
// UserService.cs
public User GetUser(long userId)
{
var user = _userRepository.GetUser(userId);
return user;
}
Somewhere in your controller, where an error is expected, you can return the error like this:
// UserController.cs
[HttpGet("{userId}")]
public IActionResult GetUserDetail(long userId)
{
var user = _userService.GetUser(userId);
if (user == null)
{
// Explicitly return the error
var error = new UserNotFoundError(userId);
return error.ToProblemResult();
}
// Omited for brevity
}
In the above snippet, where the user is not found, a response of status code 404 will be returned with the following body:
{ "type": "UserNotFoundError", "title": "User Not Found Error", "status": 404, "detail": "The error is thrown because the requested resource of type `User` could not be found", "instance": "/users/123", "data": { "userId": 123 } }
The XML comments for the class will be used to generate the detail information about the error. It can be useful if you use the UI package, as the error information can be obtain via the UI.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (4)
Showing the top 4 NuGet packages that depend on DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult:
Package | Downloads |
---|---|
DotNetBrightener.WebApi.GenericCRUD
Package Description |
|
DotNetBrightener.WebApp.CommonShared
Package Description |
|
DotNetBrightener.LocaleManagement
Package Description |
|
DotNetBrightener.AspNet.Extensions.SelfDocumentedProblemResult.UI
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.