dotnet / dotnet/aspnetcore

AddApiVersioning with a custom IProblemDetailsWriter breaks both the custom and decorated IProblemDetailsWriter

Open
#62,186 1 comment 0 reactions 0 assignees View on GitHub
area-networking feature-problem-details
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

Calling `AddApiVersioning()` causes a custom IProblemDetailsWriter to be removed, and a decorated DefaultProblemDetailsWriter to be added to the ServiceProvider **while leaving the original in place.**

The function from "Asp.Versioning.Http" `IServiceCollectionExtensions.TryAddProblemDetailsRfc7231Compliance(...)` correctly looks for and finds the descriptor associated with "DefaultProblemDetailsWriter". However, that function then calls `services.Replace(...)` *which [always replaces](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.extensions.servicecollectiondescriptorextensions.replace) the **first** enumerable matching the ServiceType*. This replaces the custom writer with a decorated version of the default, while still leaving the default writer.

ProblemDetailsService iterates through an "IEnumerable" until it finds the first writer where `CanWrite(...)` is true, then stops. This is done in the order the services are registered. To ensure the default writer is not called accidentally, I must register my custom provider before calling `AddProblemDetails()`. This triggers the bug.

### Expected Behavior

My custom `IProblemDetailsWriter` continues to work as expected. If it cannot write, then the DefaultProblemDetailsWriter is augmented by `AddApiVersioning()`.

### Steps To Reproduce

```
var builder = WebApplication.CreateBuilder();
builder.Services.AddSingleton();
builder.Services.AddProblemDetails();
builder.Services.AddApiVersioning();
```

Inspect builder.Services and CustomProblemDetailsWriter will have been removed.

### Exceptions (if any)

None

### .NET Version

9.0.203

### Anything else?

* IDE: Microsoft Visual Studio Professional 2022 (64-bit) - Current Version 17.13.6
* TargetFramework: net8.0
* dotnet --info
```
.NET SDK:
Version: 9.0.203
Commit: dc7acfa194
Workload version: 9.0.200-manifests.12d79ccf
MSBuild version: 17.13.20+a4ef1e90f

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19044
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.203\

.NET workloads installed:
[aspire]
Installation Source: VS 17.13.35931.197
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\PROGRAM FILES\DOTNET\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi

Configured to use loose manifests when installing new manifests.

Host:
Version: 9.0.4
Architecture: x64
Commit: f57e6dc747

.NET SDKs installed:
8.0.408 [C:\Program Files\dotnet\sdk]
9.0.203 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 8.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.