Skip to content

Conversation

@yringler
Copy link

I have some non-trivial customizations to JsonApiSerializer (which may be interesting to the larger community, but I'll leave that for another time).

I overrode ResourceObjectConverter, but could not figure out why it wasn't being called. I tried debugging - it wasn't being touched.

Finally, I looked through JsonApiSerializer source, and saw in the constructor of the settings

public JsonApiSerializerSettings(JsonConverter resourceObjectConverter)
{
  ...
  ContractResolver = new JsonApiContractResolver(resourceObjectConverter);
  ...

Which meant that when I set the ContractResolver property post construction, I was losing my custom JsonConverter!
The solution, of course, was to pass in my custom JsonConverter to my custom ContractResolver constructor.

However, I think that should be documented, to save others the - experience that I had.

@yringler yringler changed the title Document "gotcha" which could cause accedental setting loss Document "gotcha" which could cause accidental setting loss Oct 22, 2018
@yringler yringler changed the title Document "gotcha" which could cause accidental setting loss Document setting ContractResolver as over-riding custom JsonConverter passed into JsonApiSerializerSettings constructor Oct 22, 2018
@yringler yringler changed the title Document setting ContractResolver as over-riding custom JsonConverter passed into JsonApiSerializerSettings constructor Document: setting ContractResolver overrides custom JsonConverter passed into JsonApiSerializerSettings constructor Oct 22, 2018
@alex-davies
Copy link
Collaborator

I agree that the documentation doesn't make this particularly clear

Although i'm not sure that mentioning while discussing how to deserialize different types is the right place.

It might be worth having another section for "Json.net compatibility" and explain that the functionality is hinged off the JsonApiContractResolver so using any other contract resolver will cause issues. Then it can be followed up with settings that you can change such as NamingStrategy (which is what 99% of people want to change the ContractResolver for)

@yringler
Copy link
Author

Maybe the new section should be "Customizing JsonApiSerializer"

I feel like that more closely matches what people want to know, namely "How do I customize this?".
It is within that context, after they read that customization is via the standard Json.Net patterns, that there is interest in Json.Net compatibility.

Then in that section we could discuss

  1. Compatibility with Json.Net, that there are properties of the JsonSerializerSettings that could be set, as documented on newtonsoft
  2. JsonApiSerializer relies on the ResourceObjectConvertor (JsonConverter) being used by the JsonApiContractResolver (ContractResolver)
  3. Passing in a custom JsonConverter to the constructor is implemented via the ContractResolver, and if you want to specify the ContractResolver also, make sure that it inherits ResourceObjectConvertor and construct that with your custom JsonConverter instead of JsonApiSerializerSettings

@alex-davies
Copy link
Collaborator

@yringler a "Customizing JsonApiSerializer" section would make a lot of sense

@alex-davies
Copy link
Collaborator

Out of curiosity what is your reason for creating a custom ResourceObjectConverter?

I ask because i'm considering modifying the way such customisations are done; moving the common customisation cases to properties within the JsonApiSerizlierSettings. Naturally this would a breaking change and be a major version bump, but would be good to get some idea of what customisations people are doing

@yringler
Copy link
Author

yringler commented Oct 26, 2018

To de/serialize classes with interger Id fields.

JsonApiSerializer only serializes classes with a string Id property as a JSON:API resource. Because in our code base we have mostly/exclusively integer ids, I made a custom ResourceObjectConverter to de/serialize integer Id properties as strings.

It works by setting the type of the Id property to string, and then using a custom ValueProvider to work with the integer property on the class.

Also, sometimes we want the Id property to be called something else on the model, so I made an attribute which specifies the "backing field" for the Id property, and use it in our custom ResourceObjectConverter.

See my gist here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants