How do I implement Post([FromBody] IMessage msg) in my .Net Core 2.1 web api Controller?


How do I implement Post([FromBody] IMessage msg) in my .Net Core 2.1 web api Controller?
I get the following exception when I send a simple JSON structure implementing the interface IMessage:
Could not create an instance of type TestService2.IMessage. Type is an interface or abstract class and cannot be instantiated. Path 'Id', line 2, position 7.
My question would be Why do you want to use am interface for the model parameter?
– Nkosi
Jul 27 at 15:00
@Nkosi Good Question. I don't know. I'm implementing specifications.
– A. Non
Jul 27 at 15:09
and how would I implement such a model binder?
– A. Non
Jul 27 at 15:22
docs.microsoft.com/en-us/aspnet/core/mvc/advanced/…
– Nkosi
Jul 27 at 15:23
1 Answer
1
I absolutely agree that using classes is the way to go!
If, however, for some obscure/Stupid reason, you have to use interfaces like me, there is a simple way of mapping it to a class with JSON.
In the Startup Method, define the Contracts for the interface:
services.AddMvc()
.AddJsonOptions(o => { o.SerializerSettings.ContractResolver.ResolveContract(typeof(IMessage)).Converter = new MyJsonConverter<IMessage, Message>();})
Where IMessage is said interface, and MyJsonConverter is derived from JsonConverter, for example:
public class MyJsonConverter<Tin, Tout> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
//Your logic here
return (objectType == typeof(Tin) );
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//deserializing from the implementation Class
return serializer.Deserialize<Tout>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//use standard serialization
serializer.Serialize(writer, value);
}
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Action parameters by default have to be concrete classes that can be initialized by the model binder. Only custom model binders can be used to achieve what it is you are trying to do.
– Nkosi
Jul 27 at 14:53