Skip to main content

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:

  1. Default Mapping is Disabled: It configures ApiBehaviorOptions to turn off the built-in ClientErrorMapping, preventing MVC from generating its own responses for client errors (like 404s) before the middleware can handle them.
  2. Error Response Types: It adds a ProducesErrorResponseTypeAttribute to actions within controllers decorated with ApiControllerAttribute, signaling that the error response type is ProblemDetails.
  3. Result Transformation: It registers a result filter that automatically transforms ObjectResult instances containing a string into structured ProblemDetails responses.
  4. Factory Redirection: It replaces the standard MVC ProblemDetailsFactory with a registration that forwards requests to the middleware's own ProblemDetailsFactory.

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.");
}