Custom model binder with IDictionary<string, object>

Viewed 22

I have a .NET 6 REST API with a method that has two parameters:

public async Task<object> CreateSingleEntity([FromRoute] string entity, [FromBody] IDictionary<string, object> model)
{
    //process data
}

This works well when I do this request:

curl --location --request POST 'https://localhost:7299/api/data/cars' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
    "model": 1,
    "name": "Ford",
    "id":"a47d52de-fcd1-48e7-8656-7edb84dc78bd",
    "is_created": true,
    "date":"2022-09-23",
    "datetime":"2022-09-23 13:10"
}'

But because I'm using MediatR I'd like to use a model instead.

public class CreateSingleRecord : ICommand<object>
{
    [FromRoute(Name ="entity")]
    public string Entity { get; init; }

    [FromBody]
    public IDictionary<string, object> Record { get; init; }
}

sadly every time I try to replace my previous method with:

public async Task<object> CreateSingleEntity([FromHybrid] CreateSingleRecord model)
{
    //process data
}

I'm getting errors:

{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-0b9809f4e2a656dd8b0255940ce84db7-49b9b11c21ce132a-00", "errors": { "Record": [ "The Record field is required." ] } }

I've tried using [FromHybrid] model binder but sadly it isn't working with dictionary types.

The endpoint must handle dynamic objects because the whole system is very dynamic, so I can't bind to predefined models.

I think the only way is to create a model binder, but I have no clue how to deserialize the entire body as a dictionary and assign it to my model's property.

0 Answers
Related