RDG006: Invalid constructor parameters

Value
Rule ID RDG006
Fix is breaking or non-breaking Non-breaking

Cause

This diagnostic is emitted by the Request Delegate Generator when an endpoint contains a route handler with a parameter annotated with the [AsParameters] attribute that contains an invalid constructor.

Rule description

Types that are used for surrogate binding via the [AsParameters] attribute must contain a public parameterized constructor where all parameters to the constructor match the public properties declared on the type. The TodoRequest type produces this diagnostic because there is no matching constructor parameter for the Todo property.

using System.Text.Json.Serialization;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0,
                                       AppJsonSerializerContext.Default);
});

var app = builder.Build();

app.MapPut("/v1/todos/{id}",
           ([AsParameters] TodoRequest todoRequest) => Results.Ok(todoRequest.Todo));

app.Run();

class TodoRequest(int id, string name)
{
    public int Id { get; set; } = id;
    public Todo? Todo { get; set; }
}

record Todo(int Id, string Task);

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

How to fix violations

Ensure that all properties on the type have a matching parameter on the constructor.

using System.Text.Json.Serialization;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0,
                                 AppJsonSerializerContext.Default);
});

var app = builder.Build();

app.MapPut("/v1/todos/{id}",
           ([AsParameters] TodoRequest todoRequest) => Results.Ok(todoRequest.Todo));

app.Run();

class TodoRequest(int id, Todo? todo)
{
    public int Id { get; set; } = id;
    public Todo? Todo { get; set; } = todo;
}

record Todo(int Id, string Task);

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

When to suppress warnings

This warning should not be suppressed. Suppressing the warning leads to a runtime exception associated with the same warning.