dotnet / dotnet/aspnetcore

[FromForm] in minimal API results in null when the class is using primary constructor and default constructor

Open
#51,379 1 comment 1 reaction 0 assignees View on GitHub
area-minimal
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

The following code works fine when using with [FromForm] model binding

``` csharp
public class BlogPostInput(string? title, string body)
{
public string? Title { get; set; } = title;
public string Body { get; set; } = body;
}
```
but the following class definition will make the binding produce `null`.
``` csharp
public class BlogPostInput(string? title, string body)
{
public string? Title { get; set; } = title;
public string Body { get; set; } = body;

public BlogPostInput() : this(null, string.Empty)
{

}
}
```

### Expected Behavior

It should just work the same

### Steps To Reproduce

```csharp

using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(Template($$"""






Title



Body


Submit



"""), "text/html");
});

app.MapPost("/", async ([FromForm] BlogPostInput input, HttpContext context, IAntiforgery antiforgery) =>
{
try
{
await antiforgery.ValidateRequestAsync(context);
return Results.Content(Template($$"""



Title : {{input.Title}}

Body : {{input.Body}}


"""), "text/html");
}
catch (AntiforgeryValidationException)
{
return TypedResults.BadRequest("Invalid anti-forgery token");
}
});

app.Run();

static string Template(string body)
{
return $$"""


Form Model Binding




Form Model Binding


{{body}}



""";
}

public class BlogPostInput(string? title, string body)
{
public string? Title { get; set; } = title;
public string Body { get; set; } = body;

public BlogPostInput() : this(null, string.Empty)
{

}
}
```

### Exceptions (if any)

```
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HMUCMJP38BUA", Request id "0HMUCMJP38BUA:00000006": An unhandled exception was thrown by the application.
System.NullReferenceException: Object reference not set to an instance of an object.
at Program.<>c.<<$>b__0_1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)
at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass104_2.<b__2>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryMiddleware.InvokeAwaited(HttpContext context)
at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
```

### .NET Version

8.0.100-rc.2.23502.2

### Anything else?

It used to work in RC1

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.