joukevandermaas / saule

JSON API library for ASP.Net Web API 2.
https://joukevandermaas.github.io/saule
MIT License
76 stars 37 forks source link

Abstract / Derived Class Deserialization #200

Open aariabov opened 6 years ago

aariabov commented 6 years ago

Hello. I have model binding problem, like this. Can I make such binding with json api and saule?

joukevandermaas commented 6 years ago

It doesn't really seem to fit very nicely in the JSON api spec to do such a thing. Especially since the $type value must be the first value in the object. Perhaps it could work if you create an attribute named $type?

public class MyResource : ApiResource
{
  public MyResource()
  {
    Attribute("$type");
  }
}

then in your payload:

{
  "data": {
    "type": "my-type",
    "attributes": {
      "$type": "MyApp.Api.ConcreteType"
    }
  }
}

I suppose the "recommended" way to do it using JSON API is to set different types for the different subclasses under the data hash.

PhyberApex commented 6 years ago

I came here to ask something very similliar. Right now iirc the "type" parameter sent by the client is not interpreted at all in the deserialization. It would be great if we had a way to do this. ALSO it would be great to be allowed to return multiple APIResources that are derived from each other from a webapi action.

~Cheers

PhyberApex commented 6 years ago

Just came back to tell @aariabov that he probably can make use of the Default settings for the used Newtonsoft serializer. I just added these lines:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto,
};

and was able to use derived classed in nested attributes. To use derived classes in top level (ApiResources) would probably require a lot of work on Saule and should be really thought about as it seems to go against the RESTful philosphy and actually would be better suited for RPC.

~Cheers