CBL .NET: Nested objects returning JObject from Properties?

372 views
Skip to first unread message

ryan.t...@fieldsync.net

unread,
Oct 22, 2014, 6:02:09 PM10/22/14
to mobile-c...@googlegroups.com


Hi - a quick question about Couchbase Lite .NET. I did quite a bit of searching and couldn't find any information about this, so here goes:

I have the following document in my database with id "myDoc":

{
   
"nestedObject": {
       
"name": "Nesty",
       
"someProperty": true
   
},
   
"someArray": [
       
"Red", "Green", "Blue"
   
]
}

Here's my code:

// Get the database and document
var database = Manager.SharedInstance.GetDatabase("myDatabase");
var doc = database.GetDocument("myDoc");

// Get the property and write its type to Console
var property = doc.GetProperty("nestedObject");
Console.WriteLine(property.GetType().AssemblyQualifiedName); // Returns Newtonsoft.Json.Linq.JObject??

I would have expected to get back an IDictionary<string, object> from GetProperty when accessing the nested object. So now if want to get at 'someProperty' I have to do this:

var property = (JObject)doc.GetProperty("nestedObject");
var someProperty = (bool)property["someProperty"];

Similarly, look at this code:

var property = doc.GetProperty("someArray");
Console.WriteLine(property.GetType().AssemblyQualifiedName); // Returns Newtonsoft.Json.Linq.JArray??


Is this the intended behavior, or am I missing something? I actually think this is kind of cool, because the Json.NET's LINQ-to-JSON API is really cool. I really wish you could do this:

JObject docObject = doc.ToJObject(); // Or something similar


So anyway, my main question here is:  If I rely on these underlying Json.NET objects, will they be pulled out from under me at some point in the future, or is this the way it will stay?

Zachary Gramana

unread,
Oct 23, 2014, 1:52:30 PM10/23/14
to mobile-c...@googlegroups.com
Ryan,

Thanks for the post. Great question. I'm going to answer in-line below.


Is this the intended behavior, or am I missing something? I actually think this is kind of cool, because the Json.NET's LINQ-to-JSON API is really cool. I really wish you could do this:

JObject docObject = doc.ToJObject(); // Or something similar

Yes, it is the "intended" behavior. I use the scare-quotes because really, I'm punted. As a library designer, I try to make as a few decisions for you, the user, as possible. In this case, I didn't want to much about with embedded objects because I have no way of knowing what their original type was, and it's a bit tedious to deal with lots of nested dictionaries. At best, if you, as the user, know that "nestedObject" is a dictionary, you can at least do is something like props["nestedObject"]["name"], but that still is awkward. Instead of using standard generic dictionaries, I could create a custom class with an indexer that would allow for stuff like props["nestedObject.name"]. While that's better, I think most people are just going to want to work with their own domain models. Plus, it would be a lot of work and it's not a typical C# pattern (apart from some data-binding libraries).

So, I opted to leave things as is, and let the developer handle those decisions for now. I've discussed this with some other people, and we all feel like it's sort of surprising when you come across this, but is ultimately appreciated. We will be adding a convenience API eventually that will handle deserializing the entire object graph for you, but I expect that to be implemented as extension methods so it wouldn't change any existing behaviors. It would just handle .ToObject<T> for you. That way, if you need to do some special processing during deserialization, you can. It may also require the user use JSON.NET support for JSON-SCHEMA, or something similar. This has to be very well thought out, however, and so we won't be rushing into it. We want it to be as low friction as possible.
 
So anyway, my main question here is:  If I rely on these underlying Json.NET objects, will they be pulled out from under me at some point in the future, or is this the way it will stay?

Well, you have a lot of say in this. I'm leaning toward maintaining it as a contract, but ultimately, the community gets a large say in the matter. ;) 

ryan.t...@fieldsync.net

unread,
Oct 23, 2014, 4:53:08 PM10/23/14
to mobile-c...@googlegroups.com
Thanks for the insight. I support leaving it the way it is, because it makes interop with my existing code that relies on Json.NET quite a bit easier. It's definitely tedious to have to pass around things like IList<IDictionary<string, object>> when the object graphs get more complicated.

Roman Friedman

unread,
Dec 3, 2014, 8:35:33 PM12/3/14
to mobile-c...@googlegroups.com
Totally agree with Ryan. Would definitely make my life much easier if JSON.NET api was available in queries, map functions and documents. Without serializing and deserializing (basically twice). The fact that it's there in queryRow for view and not in document really touched my nerve a little bit. Please expose it.
Reply all
Reply to author
Forward
0 new messages