Problem details
Overview
RESTful API conventions like NotFoundResultApiConvention, ProblemDetailsResultApiConvention, (see RFC 7807 ). Use this package when implementing RESTful APIs.
Install
- ASOL.Core.ProblemDetailsConventions - contains RESTful API conventions like NotFoundResultApiConvention, ProblemDetailsResultApiConvention, (see RFC 7807 ). Use this package when implementing RESTful APIs.
Usage third party libraries (NuGets)
Changelog
ASOL.Core.ProblemDetailsConventions
- 0.0.1.24129-dev
- 0.0.1.23681-dev
- 0.0.1.14310-dev
Dependency injection
Mandatory dependency injection for Problem details.
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureOptions<ProblemDetailsOptionsCustomSetup>();
services.AddProblemDetails();
}
public void Configure(IApplicationBuilder app)
{
// Top of pipeline registration
app.UseProblemDetails();
}
Problem details standard base setup
/// <summary>
/// Represents the custom problem details configuration options.
/// </summary>
public class ProblemDetailsOptionsCustomSetup : ProblemDetailsOptionsDefaultSetup
{
public ProblemDetailsOptionsCustomSetup(
IWebHostEnvironment environment,
IHttpContextAccessor httpContextAccessor,
IOptions<ApiBehaviorOptions> apiOptions)
: base(environment, httpContextAccessor, apiOptions)
{
}
/// <inheritdoc/>
public override void Configure(ProblemDetailsOptions options)
{
base.Configure(options);
// This will map KeyNotFoundException to the 404 NotFound code.
options.Map<KeyNotFoundException>(ex =>
new StatusCodeProblemDetails(StatusCodes.Status404NotFound) { Detail = ex.Message });
// This will map InsufficientIdentityException to the 403 Forbidden code.
options.Map<InsufficientIdentityException>(ex =>
new StatusCodeProblemDetails(StatusCodes.Status403Forbidden) { Detail = ex.Message });
// This will map UnauthorizedAccessException to the 403 Forbidden code.
options.Map<UnauthorizedAccessException>(ex =>
new StatusCodeProblemDetails(StatusCodes.Status403Forbidden) { Detail = ex.Message });
// This will map AuthenticationException to the 401 Unauthorized code.
options.Map<AuthenticationException>(ex =>
new StatusCodeProblemDetails(StatusCodes.Status401Unauthorized));
// This will map ArgumentNullException to the 400 BadRequest code.
options.Map<ArgumentNullException>(ex => new ExceptionProblemDetails(ex, StatusCodes.Status400BadRequest));
// This will map processing ValidationException to the 400 BadRequest code.
options.Map<ValidationException>(ex =>
{
var rawStatus = options.MapStatusCode(null, StatusCodes.Status400BadRequest);
var validationErrors = ex.ValidationErrors.ToDictionary();
return new ValidationProblemDetails(validationErrors)
{
Type = rawStatus.Type,
Status = rawStatus.Status,
};
});
options.Map<ProcessingCoreException>(ex =>
{
switch (ex.InnerException)
{
case KeyNotFoundException inner:
{
return new StatusCodeProblemDetails(StatusCodes.Status404NotFound) { Detail = inner.Message };
}
case InsufficientIdentityException inner:
{
return new StatusCodeProblemDetails(StatusCodes.Status403Forbidden) { Detail = inner.Message };
}
case UnauthorizedAccessException inner:
{
return new StatusCodeProblemDetails(StatusCodes.Status403Forbidden) { Detail = inner.Message };
}
case AuthenticationException inner:
{
return new StatusCodeProblemDetails(StatusCodes.Status401Unauthorized);
}
case NotImplementedException inner:
{
return new ExceptionProblemDetails(inner, StatusCodes.Status501NotImplemented);
}
default:
return new ExceptionProblemDetails(ex);
}
});
}
}