C# How to serialize/deserialize an Object to/from Dictionary<string,Object> to save/load it in Couchbase.lite

If I want to store data as Document in Clouchbase.lite is has to be in the form of Dictionary like this:

var properties = new Dictionary<string, object>()
{
{“type”, “list”},
{“title”, “title”},
{“created_at”, DateTime.UtcNow.ToString (“o”)},
{“owner”, “profile:” + userId},
{“members”, new List()}
};
var rev = document.PutProperties(properties);
How can I automatically create such a Dictionary from any C# object? If I understand the couchbase.lite documentation this process does not to be recursive, just on the first level of my object fields and properties.

How can I recreate my objects from such a dictionary?

It’s not exactly that it has to be a Dictionary; it’s that it has to be convertible to JSON. That basically means that you can only use dictionaries whose keys are strings; arrays; strings; numbers; booleans; and null.

It does have to be recursive. All property values have to be convertible to JSON too.

The details of converting your objects to this form vary by language; I don’t use C# so I can’t answer in detail. Some developers just work with dictionaries, some write their own methods to convert their objects to/from dictionaries, and some use 3rd party libraries for JSON serializing/deserializing.

Hi escamoteur,

Did you figure this out yet? Your C# object should be serializable for a start. You can also use the SerializeObject method of the JSON.NET library.

using Newtonsoft.Json;
Properties["doc"] =  
JsonConvert.SerializeObject (entity, Formatting.Indented, 
new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    });

Here, entity is my serializable C# object. I use JsonConvert along with some formatting and specify to ignore reference looping to prevent circular referencing.

On the deserializing end, this works nicely where TEntity is the class of your object.

var obj = doc.UserProperties["doc"];
var model = JsonConvert.DeserializeObject<TEntity>(obj.ToString());

This will add an extra level of “doc: {}” in the JSON of all documents. I would want to put the JSON serialized string directly into the document properties, not on a sub-level. What are the downsides of having an artificial top level “doc” in all documents?

I’d like to share how to deserialize Dictionary to custom object using Newtonsoft.Json’s JObject class :

private MyCustomObject DeserializeUsingLinqToJson(string documentId)
{
    Document document = localDatabase.GetExistingDocument(documentId);
    Dictionary<string, object> properties = document.UserProperties;

    JObject obj = JObject.FromObject(properties);
    return obj.ToObject<MyCustomObject>();
}

Suppose it’s more effective than string-based JSON serialization described here.

A new open source project called Couchbase.Lite.Mapping has recently been added to the Couchbase Labs Github and to Nuget . It allows for converting model objects to and from MutableDocument objects. It’s still an ongoing effort, and we’re hoping to get some feedback on specific use cases. If you have time please give it a try and let us know what you think.

Hi Robert

It would be awesome if “someone” added the usage of the mapping package to this sample app: https://github.com/couchbaselabs/mobile-travel-sample/tree/master/dotnet :smiley:

I’m in the middle of architecting a fairly large app (using Xamarin Forms and Prism) - and I must admit I’m as bit challenged as to how to best combine the thoughts in the demo and a standard Prism project into a “pretty good practice”…

I know its not Couchbase’s job to teach me that - however, I like to see the good samples.

One thing that I’m curious about is:

  • In the travel-sample app the models contain the actual query code
  • In the mapping examples the model simply contains the properties

So should I just combine those two by adding the methods inside the model? It doesn’t feel quite right…

Ok, just reviewed the project again - and the “real” model (or rather data class) is actually inside the viewmodel class… - not sure that is best practice either… Well, anyway, good samples of structures and code that would work in the “real world” are always good to learn from - and typically we (the “users” of your product) end up building better apps - to the benefit of all :wink:

Hey @jda !

First things first, thank you for taking a look at the Couchbase.Lite.Mapping package!

As you’ve likely noticed, it’s a fairly simple project meant for a singular purpose: converting basic storage objects/models to/from Couchbase Lite objects (i.e. MutableDocument, Document, Result). Essentially, it provides a flexible approach to help reduce the amount of boilerplate code written when mapping your own objects to and from Couchbase Lite objects. It’s purposely generic (no pun intended) to maximize flexibility, not to narrow its scope of use based on architectural requirements. Depending on your exact needs the extension methods provided in Couchbase.Lite.Mapping may not fit your needs, and you’d instead need to map the data in the default manner. That being said, if you see some potential to expand on its current functionality let’s collaborate!

Secondly, you bring up very valid points about the use (and just general confusion) of the MVVM design pattern. If you spend some time digging around you’ll find that people are highly opinionated as to where business and service should live. You’ll find content that recommends keeping business logic within the model, and keeping view models strictly focused on exposing functionality for the view. However, if you throw “services” into the mix you’ll find that business logic can be moved out of both the model and view model, but that’s a whole other “can of worms”. Ultimately, we tend to shy away from recommending one particular architectural approach as your app’s architecture will boil down to your use case where things like code reuse (inter-app, for example), unit/ui testing, etc. will need to be considered.

Some other examples I’d recommend taking at a look are some recent tutorials we’ve created for Xamarin apps:

Please don’t hesitate to give us any and all feedback on the tutorials, as our primary goal is to create the most relevant content we can.

Lastly, because Couchbase.Lite.Mapping isn’t officially supported by Couchbase we’ve opted not to include it in samples like the travel app. However, I agree that providing a more robust example using the mapping component would be useful, and will work on providing one. If you have any app ideas, or functionality you’d like to see included in these samples beyond the use of the mapping Nuget package please let me know!