Add problem-details MVC conventions
When you use standard ASP.NET Core MVC controllers, the framework's built-in client error mapping can sometimes conflict with the custom error responses generated by Middleware. The AddProblemDetailsConventions extension method ensures that MVC's behavior is aligned with the middleware's response generation by disabling default mappings and injecting specific filters.
MVC Integration Contract
The AddProblemDetailsConventions method, located in the Hellang.Middleware.ProblemDetails.Mvc namespace, provides a way to register MVC-specific behaviors directly onto an IServiceCollection. This is particularly useful when you want to ensure that:
- Default Mapping is Disabled: It configures
ApiBehaviorOptionsto turn off the built-inClientErrorMapping, preventing MVC from generating its own responses for client errors (like 404s) before the middleware can handle them. - Error Response Types: It adds a
ProducesErrorResponseTypeAttributeto actions within controllers decorated withApiControllerAttribute, signaling that the error response type isProblemDetails. - Result Transformation: It registers a result filter that automatically transforms
ObjectResultinstances containing astringinto structuredProblemDetailsresponses. - Factory Redirection: It replaces the standard MVC
ProblemDetailsFactorywith a registration that forwards requests to the middleware's ownProblemDetailsFactory.
The method follows the standard .NET builder pattern, returning the same IServiceCollection instance to allow for fluent registration chaining.
using System;
using Hellang.Middleware.ProblemDetails.Mvc;
using Microsoft.Extensions.DependencyInjection;
// Initialize a new service collection
var services = new ServiceCollection();
// Register the MVC conventions for ProblemDetails
// This method 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("The IServiceCollection returned was not the same instance.");
}