You can also use custom TextInputFormatter, no external libraries needed, also helps you gain insight on how you can handle (de)serialization of any type of data.
public class MyInputTypeFormatter : TextInputFormatter
{
public MyInputTypeFormatter()
{
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
SupportedEncodings.Add(Encoding.UTF8);
}
protected override bool CanReadType(Type type)
{
return type == typeof(MyClass);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var httpContext = context.HttpContext;
var serviceProvider = httpContext.RequestServices;
var logger = serviceProvider.GetRequiredService<ILogger<ImageTypeConverter>>();
using var reader = new StreamReader(httpContext.Request.Body, encoding);
{
var data = await reader.ReadToEndAsync();
if (data.Contains("Hello"))
{
var myClass= new MyClass(data);
return await InputFormatterResult.SuccessAsync(myClass);
}
else
{
return await InputFormatterResult.FailureAsync();
}
}
}
}
Then, simply add this input formatter to the list of input formatters with
services.AddControllers(options=> {
options.InputFormatters.Insert(0, new MyInputFormatter());
});
0 here means this is the first input formatter invoked when model binding.
It seems like a lot of work but most of it is just boilerplate.
I will explain how this works,
You have an action method/ route which has a parameter of MyClass type. When a request comes to it, your input formatter's CanReadType is invoked and it returns true meaning it will handle the deserialization.Then the ReadRequestBodyAsync method is invoked and the request data is given to it.
You can do whatever you want with the data and return an object of type MyClass if your deserialization succeeds. Else you just return a failure.
In the deserialization you can use
using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
// ...
}
You can traverse elements as the input is parsed into a json object and then held into a DOM. Then you can see what they contain and manually create classes with their data and convert your input-as-interfaces into classes.
Note: JsonDocument was introduced in .Net 3.1
You can check out how to use it here
More about how to use TextInputFormatter and TextOutputFormatter
The benefit of using a custom input formatter is that it provides a central class for handling your custom classes which may use multiple interfaces. It also gives you fine control over handling the input data.