Object Serialization

.net

#1

hello, I am using Couchbase Lite for quite a while and now I have switched vorm 1.x -> 2.X with some major problems. In 1.x I was converting my data with JSON to a dictionary, with most proposed way here in the forum:

   public static Dictionary<string, object> ToCouchDictionary<tt>(this tt obj)
    {
        var json = JsonConvert.SerializeObject(obj);
        var jsonToDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
        return jsonToDict;
    }

    public static tt ToObject<tt>(this IDictionary<string, object> dict)
    {
        var json = JsonConvert.SerializeObject(dict);
        var obj = JsonConvert.DeserializeObject<tt>(json);
        return obj;
    }

which worked really great, I know not the most performant way…

I wanted to reuse this approach for 2.x but when i instantiate the MutableDoc with:

var dict = obj.ToCouchDictionary();
using (var mutableDoc = new MutableDocument(dict))
{

simply nothing happens when the new is called. Not even an exception is raised (i tried already to improve exception settings). I see no reason why this approach should not work any more…
any ideas?

Thank you!


#2

I’m unsure of what you mean by this:

What are you expecting to happen?


#3

I would expect that the MutableDoc is created the same way it was in 1.x.
OR an exception with an information is thrown and not caught somewhere in the lib.

Actually i was able to adapt my debugger settings and there is an
Exception thrown: ‘System.ArgumentException’ in Couchbase.Lite.dll in

InMemoryDictonary.cs

line 228:

public IMutableDictionary SetData(IDictionary<string, object> dictionary)
{
_dict = dictionary.ToDictionary(x => x.Key, x => DataOps.ToCouchbaseObject(x.Value));
HasChanges = true;
return this;
}

I think it is the ToCouchbaseObject Function but I cannot go any deeper with the debugger.


#4

It sounds like you probably have invalid object types inside of your JSON. Couchbase Lite 2 restricts the type of information you can put into it, and I think the dynamic is where it is getting into trouble (consult the message of the exception for more information). That exception should reach you in that case as there is nowhere that catches it in the CBL code base. What happens if you wrap it in a try / catch statement?

Another thing to note is that unlike 1.x, the documents are created in-memory only unless they are retrieved from the DB so you won’t see them in a database until you save them.


#5

actually the dynamic was just a desperate try and this is wrong I am using Dictionary<string, object> and as i said exactly this code is working with the same document structure in 1.x.
Now I could debug the single items of my object in the line 228

_dict = dictionary.ToDictionary(x => x.Key, x => DataOps.ToCouchbaseObject(x.Value));

my object contains only simple datatypes and the problem is with the DateTime. When
DataOps.ToCouchbaseObject is called and x.Value is of Type DateTime the ArgumentException is thrown…


#6

actually my code is inside a try/catch but nothing is raised, i just see it in the output window. It seems that whole lite.core instance crashes…


#7

You need to instruct Json .NET to use DateTimeOffset instead (you can specify this in the serialization settings for JSON .NET with the DateParseHandling enum.


#8

Thank you, serialization works now. Here is the adapted code, for anyone who has the same problem:

public static Dictionary<string, object> ToCouchDictionary(this tt obj)
{
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DateParseHandling = DateParseHandling.None
};

        var json = JsonConvert.SerializeObject(obj) ;
        var jsonToDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
        return jsonToDict;
    }

but deserialization of the stored object does not work any more…
in 1.x the Id field was mapped to json property _id which stored the id of the returned document.
Now this does not work any more…


#9

sorry now i found out what problem was, it was related to the Query which does not return the full dictionary. Now i return the ID and with the id i can get the full object


#10

The _id and _rev properties were just a relic from CouchDB; we took them out in 2.0 because they’re not necessary and make document processing more expensive.

The 2.0 API means you don’t have to deal with JSON serialization anymore. Just use our document API to work with document properties.