Add problem-details MVC conventions
When building APIs with ASP.NET Core MVC, the framework provides built-in mechanisms for handling client errors and generating responses. However, to ensure consistency between MVC-generated errors (like validation failures) and the custom error handling provided by Middleware, you must align the MVC conventions with the Middleware's ProblemDetails logic.
The AddProblemDetailsConventions extension method in Hellang.Middleware.ProblemDetails.Mvc establishes this alignment by modifying how MVC handles error responses. Specifically, it:
- Replaces the Default Factory: It swaps the standard MVC
ProblemDetailsFactorywith theProblemDetailsFactoryused by Middleware, ensuring that allProblemDetailsobjects are created using the same configuration. - Disables Default Mapping: It configures
ApiBehaviorOptionsto turn off the built-inClientErrorMapping, preventing MVC from generating its own default error responses that might conflict with your custom middleware logic. - Applies Application Models: It registers a
ProblemDetailsApplicationModelProviderto automatically addProducesErrorResponseTypeAttributeto controllers decorated withApiControllerAttribute. - Transforms Results: It sets up filters to transform
ObjectResultinstances containing strings into structuredProblemDetailsresponses.
To register these conventions, call the extension method on your IServiceCollection during the service configuration phase. The method follows a fluent interface pattern, returning the same IServiceCollection instance to allow for further chaining.
using System;
using Hellang.Middleware.ProblemDetails.Mvc;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
// Register the MVC conventions for ProblemDetails.
// This returns the same IServiceCollection instance for chaining.
var returnedServices = services.AddProblemDetailsConventions();
// Verify the public registration contract: the method must return the original collection.
if (!object.ReferenceEquals(services, returnedServices))
{
throw new InvalidOperationException("AddProblemDetailsConventions did not return the original IServiceCollection.");
}