Combining custom camel case serializer with LINQ
See original GitHub issueThe SDK supports a custom serializer by deriving from CosmosSerializer
but using a serializer that converts idiomatic C# pascal case property names to JSON camel case names break LINQ queries.
Version 3.2.0-preview2 now supports CosmosPropertyNamingPolicy.CamelCase
which fixes the camel case problem. Thanks!
However, it is impossible to both have a custom serializer and also a LINQ provider that uses camel case. If I specify a custom serializer then I’m no longer allowed to use CosmosPropertyNamingPolicy.CamelCase
which I need to change the behavior of the LINQ provider to match my custom serializer.
Would it be possible to both configure the LINQ provider to generate camel case SQL while also using a custom serializer? That would be awesome.
Related issues: #72, #551, #570.
And just to explain why I need a custom serializer here are some of the reasons:
- I have some code generated types that my serializer is able to serialize based on an attribute so number-like types are serialized as numbers and not strings.
- I have abstract base types and concrete derived types which JSON doesn’t support but my serializer is able to deserialize to the correct derived type based on additional light-weight type information in the JSON.
- I have some custom types that I use as dictionary keys which also require extra support from the serializer.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:14
- Comments:11 (4 by maintainers)
Top GitHub Comments
bump
Here are some additional thoughts on how to handle this issue which may be relevant to users of the Cosmos SDK (people like me, not the developers of the SDK).
I’m building my system in C# and I use the type system to assist me in doing that which includes using inheritance and combatting primitive obsession with dedicated value types.
Unfortunately, there is some impedance mismatch between C# types and JSON. To handle this I have had to customize the JSON serializer and this customization has only grown over time. This has resulted in a heavy dependency on
Json.NET
.The most recent release of the Cosmos SDK has good support for camel case/pascal case but then I can no longer use my customized serializer. Essentially I was still stuck at
[JsonProperty]
all over my domain model (no, that doesn’t scale at all),The fundamental problem here is that intersection of my domain model, my desire to use LINQ, a requirement that all JSON is camel cased to avoid client side confusion, and the Cosmos SDK is empty.
Also, having a strong dependency on
Json.NET
has been a concern of mine. I would like to be able to switch toSystem.Text.Json
in the future where it might end up being the “default” serializer with only “legacy” software usingJson.NET
.As Cosmos SDK works quite well for “simple” POCO types (especially with the latest addition to support camel case) I realized that I could solve my problem by inserting a “DTO layer” with “JSON friendly” types between my domain model and lower layers like JSON serialization, Cosmos SDK etc. This would remove all the trouble I’m having with using a specific JSON serializer and a specific Cosmos SDK. If I want camel case I can just generate the DTOs with camel case and handle that in my own mapper.
I don’t want to write a ton of DTOs by hand so instead I’ve created a system where “JSON friendly” DTOs are generated at run-time (using Roslyn). I already had a mapper in place to automatically map between domain types and DTOs and my DTO generator expands on specific conventions of my type system. Creating a general library to do this is a major undertaking so I have opted to just support the specific types I use to limit the scope.
To sum up writing to Cosmos involves the following steps:
Reading is more or less the same just going the opposite way. The most tricky part is probably rewriting the “domain layer” LINQ expressions to equivalent “DTO layer” expressions which enables LINQ queries.
I admit that there were far more devils found in the details than I expected when building this but I’m quite happy with the final results.