Custom Model Binding

Converts incoming request data into strongly typed key arguments.

Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using Foo.Api.Application.Infrastructure.ModelBinders;
using Microsoft.AspNetCore.Mvc;
using System;

namespace Foo.Api.Application.Models
{
public class Artist
{
public Artist(Guid id, string name)
{
Id = id;
Name = name;
}

[ModelBinder(BinderType = typeof(JsonModelBinder))]
public Guid Id { get; private set; }

[ModelBinder(BinderType = typeof(JsonModelBinder))]
public string Name { get; private set; }
}
}

JsonModelBinder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace Foo.Api.Application.Infrastructure.ModelBinders
{
public class JsonModelBinder : IModelBinder
{
private readonly JsonSerializerOptions serializerOption = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter() }
};

public Task BindModelAsync(ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider
.GetValue(bindingContext.FieldName);

if (string.IsNullOrEmpty(value.FirstValue))
return Task.CompletedTask;

var result = JsonSerializer
.Deserialize(value.FirstValue, bindingContext.ModelType, serializerOption);

bindingContext.Result = ModelBindingResult.Success(result);

return Task.CompletedTask;
}
}
}