Using [FromForm] in Web API controller action when object contains a delegate causes memory leak
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
We have a large MVC application with some Web API controllers in the same project. A developer has re-used an existing ViewModel class as input to a separate Web API controller action.
I noticed a memory leak when `[FromForm]` was used to decorate a parameter on this action with this ViewModel class being the parameter's type and that ViewModel class also containing a property whose type is a delegate (either `Action` or `Func`).
For example:
```C#
[ApiController]
[Route("api/test/[action]")]
public class TestApiController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromForm] SomeViewModel _)
{
// do stuff
return Ok();
}
}
public class SomeViewModel
{
// Using this with [FromForm] causes memory leak
[BindNever, ValidateNever, JsonIgnore] // does not fix it
public Func Func { get; set; }
}
```
The RAM usage on my Windows 11 machine keeps increasing until it reaches 98-100% and Visual Studio slows down.
I tried decorating the property with `[BindNever, ValidateNever, JsonIgnore]` attributes but that does not solve the issue.
### Expected Behavior
The developer re-used the ViewModel class because it contains a lot of shared values with the MVC view and the Web API controller action, so I can see why someone might want to do this (even if not best practice) and how it would be a simple mistake to make.
It took a while to figure out the cause of this memory leak, so I would have preferred some indication of what was causing the issue. If ASP.NET Core encounters any internal errors or memory issues then I would expect it to either throw an exception to warn the developer of the problem, or to ignore the property completely.
I was also surprised that the attributes I tried to use were not resolving the problem. I assumed the API explorer might have been trying to figure out how to scrap information from the delegate property but was causing an infinite loop of some sorts, because the MVC controllers had no issues receiving the delegate (but that's just a theory).
### Steps To Reproduce
1. Clone this repository: https://github.com/Mike-Logit/Delegate-In-Form-Input-Memory-Leak
2. Run the project in Visual Studio 2022
3. View the computer's memory usage and see it increase
Please note that this issue seems to not affect controllers used by conventional routing for MVC controllers extending the `Controller` class. Therefore, the repository linked above only includes a simple Web API controller with attribute routing and extends `ControllerBase`.
### Exceptions (if any)
(at 80% increased speed)

### .NET Version
8.0.2
### Anything else?
.NET SDK:
Version: 8.0.200
Commit: 438cab6a9d
Workload version: 8.0.200-manifests.e575128c
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.200\
.NET workloads installed:
There are no installed workloads to display.
Host:
Version: 8.0.2
Architecture: x64
Commit: 1381d5ebd2
.NET SDKs installed:
7.0.311 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]
8.0.200 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 7.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.2 [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
Assessment
This issue has not been assessed yet.