VanDerHeijden.JsonBodyProvider
10.0.8
dotnet add package VanDerHeijden.JsonBodyProvider --version 10.0.8
NuGet\Install-Package VanDerHeijden.JsonBodyProvider -Version 10.0.8
<PackageReference Include="VanDerHeijden.JsonBodyProvider" Version="10.0.8" />
<PackageVersion Include="VanDerHeijden.JsonBodyProvider" Version="10.0.8" />
<PackageReference Include="VanDerHeijden.JsonBodyProvider" />
paket add VanDerHeijden.JsonBodyProvider --version 10.0.8
#r "nuget: VanDerHeijden.JsonBodyProvider, 10.0.8"
#:package VanDerHeijden.JsonBodyProvider@10.0.8
#addin nuget:?package=VanDerHeijden.JsonBodyProvider&version=10.0.8
#tool nuget:?package=VanDerHeijden.JsonBodyProvider&version=10.0.8
VanDerHeijden.JsonBodyProvider
ASP.NET Core custom value provider
Allows you to bind multiple simple parameters directly from a JSON request body — without using [FromBody] and without wrapper DTO classes.
Main purpose
Call controller actions like this:
[HttpPost]
public IActionResult CreateUser(
string Name,
int Age,
List<string> Roles,
Guid TenantId,
DateOnly StartDate,
bool IsActive,
string? Comment = null)
{
// ← all parameters automatically come from JSON body
}
Most important facts first
Works only without [ApiController] attribute
[ApiController] breaks this completely → remove it from the controller
Installation
dotnet add package VanDerHeijden.JsonBodyProvider
Recommended minimal startup configuration
AddJsonBodyProvider extends IServiceCollection and registers the controllers itself —
do not chain it onto AddControllers().
builder.Services.AddJsonBodyProvider(
CorrectLists: true, // ← enables normal list + string behaviour (default)
ParseHeaders: false, // ← bind request headers as parameters too
ParseCookies: false, // ← bind cookies as parameters too
CaseSensitive: true); // ← match property names exactly (default)
Case sensitivity
By default property names are matched exactly: JSON { "Name": … } binds to string Name,
not to string name. This is stricter than the built-in value providers of ASP.NET Core, which
match query string, form and route values case-insensitively.
Set CaseSensitive: false to get that same relaxed matching:
builder.Services.AddJsonBodyProvider(CaseSensitive: false);
{ "USER": "alphons" } // binds to string user only when CaseSensitive is false
The switch covers the whole chain: top-level parameters, nested paths (objB.Name), the
objects inside lists, and [FromBody] deserialization — so one setting decides it all.
Good real-world examples
Example 1 – Classic user creation
[Route("api/users")]
public class UsersController : ControllerBase
{
[HttpPost]
public IActionResult Create(
string Name,
int Age,
string Email,
List<string> Roles,
bool IsActive = true)
{
// ...
}
}
POST /api/users
Content-Type: application/json
{
"Name": "Lisa van Dijk",
"Age": 34,
"Email": "lisa@example.com",
"Roles": ["editor", "reviewer"],
"IsActive": true
}
Example 2 – Order with items
[HttpPost("orders")]
public IActionResult PlaceOrder(
string OrderNumber,
DateOnly OrderDate,
decimal TotalAmount,
List<string> ProductCodes,
Guid CustomerId,
string? Remark = null)
{
// ...
}
{
"OrderNumber": "ORD-2025-78412",
"OrderDate": "2025-06-18",
"TotalAmount": 1249.95,
"ProductCodes": ["PROD-A42", "PROD-B17", "PROD-C09"],
"CustomerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"Remark": ""
}
Example 3 – Very flat analytics event
[HttpPost("events")]
public IActionResult TrackEvent(
string EventName,
string UserId,
DateTime Timestamp,
int Value,
Dictionary<string, string> Properties,
bool IsConversion,
Guid? CampaignId)
{
// ...
}
{
"EventName": "purchase_completed",
"UserId": "usr_9k3j2p8x",
"Timestamp": "2025-06-18T14:22:09Z",
"Value": 1,
"Properties": {
"Category": "electronics",
"Source": "newsletter"
},
"IsConversion": true,
"CampaignId": null
}
Example 4 – Very minimal update
[HttpPatch("items/{id}")]
public IActionResult PatchItem(
Guid id,
string? Title,
string? Description,
bool? Active,
int? Priority)
{
// only the fields that are sent will be bound
}
{
"Title": "Updated task name",
"Priority": 3
}
Example 5 – Nested objects
Parameters are not limited to flat values; nested objects and arrays bind as well.
public class GroupInfo
{
public string Name { get; set; }
public List<List<string>> Users { get; set; }
}
[HttpPost("groups")]
public IActionResult SaveGroup(string Group, GroupInfo Info)
{
// ...
}
{
"Group": "groupy",
"Info": {
"Name": "My Name is",
"Users": [["admins", "0"], ["editors", "1"], null, ["sisters", "3"]]
}
}
What you get for free
- Multiple parameters from one JSON body
- No need for
[FromBody]on every parameter - No wrapper DTO needed
- Nested objects, arrays and arrays of arrays
- Empty strings stay empty strings
- Lists behave nicely:
nullentries are preserved, so indexes never shift NaN/Infinityserialize instead of throwing, and quoted numbers are accepted- Headers and cookies are also available as parameters (optional)
Golden rule (repeat until it hurts)
Do NOT use [ApiController] on controllers where you want to use this package
If you really need [ApiController] → you cannot use this style of multi-parameter binding
License
GPL-3.0-or-later — see LICENSE
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on VanDerHeijden.JsonBodyProvider:
| Package | Downloads |
|---|---|
|
netproxy
netproxy is a lite framework for posting multiparameter data in json format to .net core controllers (including uploads and progress events) |
GitHub repositories
This package is not used by any popular GitHub repositories.