Knowing how to find answers from the incredibly useful, informal documentation that make up the collective knowledge on a subject turns out to be key. Also, paying attention helps.
When you don't it sometimes results in an well deserved face palming moment when you say, "Why didn't I find/think/know/deduce that before I shot off my big mouth?"
And that's the case when you (in this case, me) write a snarky post about how something doesn't work when maybe if you'd had better access to the collective knowledge base, you'd have saved days of work and not a little embarrassment. But then you'd be the Borg. Or is it a Borg? I don't know... maybe both.
The solution came in the form of a comment in a GitHub repository where someone shared how they'd fixed the problem. They used an option that I didn't even know existed on a method call. And that's on me because I supplied every other possible parameter to that method except that one when I wrote my generic repository.
If you haven't read this post, don't. It doesn't exist, and I don't know what you're talking about.
If you did, forget I said all that and use the steps below to get CosmosDb and
System.Text.Json working together without compromising. And bonus - future proofing your app when
System.Text.Json finally becomes the default serializer for CosmosDb.
Get a custom serializer.
You'll need a custom serializer to use instead of the
Newtonsoft.Json one that's built in. You can download that custom serializer here. It's from the
Microsoft.Azure.Cosmos.Samples repository so you can trust it.
Change your CosmosClient initialization code.
As you can see, I'm setting
PropertyNamingPolicy = JsonNamingPolicy.CamelCase so that my property names inside the document are all CamelCase. If you're new to CosmosDb, remember that there is a case sensitive, required property with a name of
id on every document.
CamelCase means I don't have to put
[JsonPropertyName("id")] on my
Id property or other Json attributes sprinkled around in my code.
What's important here is that this change does not affect the casing on
LINQ queries. So, if you stop reading here, you'll be unhappy.
Fix your LINQ queries.
If you're using
LINQ for CosmosDb you might be writing something like this:
Unfortunately, now that you're no longer using the default serializer, that
LINQ statement generates the
SQL below which has the wrong casing and yields the wrong result.
But you can fix that by changing your original query to this:
SQL generated looks like this:
As it turns out, for me anyway, I wrote a generic repository for my CosmosDb needs and I only needed to make the change in a single spot and voila, everything works as advertised.
Thanks to the people from Microsoft for responding in under 24 hours to a Tweet about this problem I was having and even more thanks for already solving it. And a special thanks to the people at DevBetter for getting this out in the wind.