This is not really a question as much as an FYI unless someone has anything valuable to add. I just went through a few hours of pain, trying to figure out why my .NET Core API route wasn't working when POSTing a specific class, with one of its properties being of another class type.
Thing was that the child property type was an abstract class and it looks like .NET Core does not support those for routing. The symptom was getting an object coming in as null, instead of any meaningful value.
To illustrate this better:
[Produces("application/json")]
[Route("api/AbstractTest")]
public class AbstractTestController : Controller
{
[HttpPost]
public async Task<IActionResult> PostEvent([FromBody]Parent parent)
{
return Json(parent);
}
}
public class Parent
{
public Child Child {get;set;}
}
public class ConcreteChild : Child
{
public string Name {get;set;
}
public abstract class Child
{
public int Id {get;set;}
}
The following will not work. POSTING a valid Parent JSON with ConcreteChild to http://localhost:xxxx/abstracttest will return a null in Postman. Simply getting rid of the abstract keyword marking the Child class will resolve this.
TL;DR: .NET does not like abstract classes being POSTed to it and will not return a meaningful error message to help in debugging
Edit: Everybody saying that this is by design is correct! I should have included the whole detail in this post my bad. The part that I omitted was the fact that I was actually passing in an object as a concrete implementation of the abstract class (mirrorred in TypeScript) and was still getting this issue with abstract type. It seems like passing a concreate type to a controller action expecting an abstract type does not work as expected - e.g. being able to automatically convert to the right concrete type.
As some of the comments have suggested, it looks like custom binders could be the answer: https://learn.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-2.0