dotnet / dotnet/aspnetcore

[FromForm] with Custom Property Names Fails to Bind in .NET 8 Minimal API, Works in MVC Controllers

Open
#58,648 5 comments 5 reactions 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

When using .NET 8 Minimal API, form data binding with customized property names via `[FromForm(Name = "some name")]` and `[JsonPropertyName("some name")]` fails to deserialize the request object, resulting in null. However, the same configuration works correctly in .NET 8 when using MVC controllers.

### Expected Behavior

The form data should be correctly deserialized into the request object in a Minimal API project when using customized property names, just like it does in a traditional MVC controller project.

### Steps To Reproduce

A minimalistic project reproducing the issue is provided below:

`Minimal API Project`

```c#

app.MapPost("/submit", ([FromForm] UserInput input, HttpContext context) =>
{
return Results.Ok(new { Message = "Form received", input });
})
.WithName("SubmitForm")
.WithOpenApi()
.DisableAntiforgery();

public class UserInput
{
[JsonPropertyName("first_name")]
[FromForm(Name = "first_name")]
public string FirstName { get; set; }

[JsonPropertyName("last_name")]
[FromForm(Name = "last_name")]
public string LastName { get; set; }
}

```

![Image](https://github.com/user-attachments/assets/68130ad6-ba76-4219-ba2d-10969d53b4ed)

![Image](https://github.com/user-attachments/assets/cc829b30-7a2f-4240-83ee-bd1ec6f863f4)

`Controller API Project`

```c#
using Microsoft.AspNetCore.Mvc;

using System.Text.Json.Serialization;

namespace WebAPI.Controllers;
[Route("api/[controller]")]
[ApiController]
public class SubmitController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromForm] UserInput input)
{
return Ok(new { Message = "Form received", input });
}
}
public class UserInput
{
[JsonPropertyName("first_name")]
[FromForm(Name = "first_name")]
public string FirstName { get; set; }

[JsonPropertyName("last_name")]
[FromForm(Name = "last_name")]
public string LastName { get; set; }
}
```

![Image](https://github.com/user-attachments/assets/2d12b245-0f5e-4e73-88a4-c214922b6304)

![Image](https://github.com/user-attachments/assets/0aa50a11-c46b-4464-a081-09d569b6f2a0)

### Exceptions (if any)

_No response_

### .NET Version

8.0.403

### Anything else?

`dotnet --info`

**.NET SDK:**
- Version: 8.0.403
- Commit: c64aa40a71
- Workload version: 8.0.400-manifests.e99c892e
- MSBuild version: 17.11.9+a69bbaaf5

**Runtime Environment:**

- OS Name: Windows
- OS Version: 10.0.19045
- OS Platform: Windows
- RID: win-x64
- Base Path: C:\Program Files\dotnet\sdk\8.0.403\

**.NET workloads installed:**
Configured to use loose manifests when installing new manifests.

- [aspire]
- Installation Source: VS 17.11.35327.3
- Manifest Version: 8.1.0/8.0.100
- Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.1.0\WorkloadManifest.json
- Install Type: FileBased

**Host:**

- Version: 8.0.10
- Architecture: x64
- Commit: 81cabf2857

**.NET SDKs installed:**

- 8.0.403 [C:\Program Files\dotnet\sdk]

**.NET runtimes installed:**

- Microsoft.AspNetCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
- Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
- Microsoft.AspNetCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
- Microsoft.NETCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
- Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
- Microsoft.NETCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
- Microsoft.WindowsDesktop.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
- Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
- Microsoft.WindowsDesktop.App 8.0.10 [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

Contributor guide

Open the contributing guide

Research direction

Start with the provided Minimal API reproduction at app.MapPost("/submit", ...) and the UserInput properties using [FromForm] and [JsonPropertyName]. Run the reproduction and compare its form binding with the controller project; done means customized first_name and last_name values bind correctly in Minimal API requests as they do in MVC.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.