Skip to content

Newtonsoft Serialization

Lukas Pirkl edited this page Jun 23, 2015 · 12 revisions

RethinkDB C# driver supports serialization via JSON.NET (Newtonsoft) serialization engine.

Getting Started

First, download the necessary references from NuGet here:

Import the following namespaces:

  • using RethinkDb;
  • using RethinkDb.Newtonsoft.Configuration;

Caution: There are two ConfigurationAssemblers in the assemblies you've referenced. Be sure you're importing the ConfigurationAssembler from RethinkDb.Newtonsoft.Configuration.

Use the ConfigurationAssembler as you normally would, by getting a IConnectionFactory with:

public class Person
{
    [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
    public Guid? Id {get;set;}
    public string Name {get;set;}
}

public static class MainClass
{
    public static void Main(string[] args)
    {
        var connFactory =  RethinkDb.Newtonsoft
                               .Configuration.ConfigurationAssembler
                               .CreateConnectionFactory("ClusterName");

        var conn = connFactory.Get();

        IDatabaseQuery db = Query.Db("test");
        ITableQuery<Person> table = Db.Table<Person>("people");

        // Insert a new record
        conn.Run(table.Insert(new Person() { Name = "Jack Black" }));
    }
}

That's it! By default, the Newtonsoft serializer uses CamelCasePropertyNamesContractResolver to camel case object properties. See [Document Modeling] (https://github.com/mfenniak/rethinkdb-net/wiki/Newtonsoft-Serialization#document-modeling) section, for why this is important.

Custom Serialization

Customizing the serlization process can be done by setting up your Json settings before creating the connection and by modifying the exposed JsonSerializerSettings on the ConfigurationAssembler. For example:

    RethinkDb.Newtonsoft.Configuration
           .ConfigurationAssembler.DefaultJsonSerializerSettings
           .Converters.Add( new StringEnumConverter() );

Important: Be sure the TimeSpanConverter in RethinkDb.Newtonsoft.Converters is always present in DefaultJsonSerializerSettings. Don't worry, it's added by default, but if you make heavy changes be sure it is present as a converter.

Document Modeling

When modeling your objects, there are some important things you need to be particularly aware of.

Primary Key Generation

There are two ways to generate primary keys for your documents:

1. Client-side primary key generation

If you plan on generating primary keys yourself (inside your program), you'll want to make sure every document has an 'id' property. 'id' is case sensitive. So, it's particularly important to decorate the "id" of your root object with correct case sensitivity. For example:

    public abstract class Document
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        protected Document()
        {
            this.Id = Guid.NewGuid().ToString();
        }
    }

    public class Person : Document
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

2. Server-side primary key generation

If you want RethinkDb to generate primary keys for you, you'll need to ensure that you omit the "id" property from your object when it's being serialized. You can do this by setting the NullValueHandling = NullValueHandling.Ignore on the JsonProperty. For example,

    public abstract class Document
    {
        [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
        public string Id { get; set; }
        // ID will be populated by RethinkDb
        // check the "GenratedKeys" from the response after
        // inserting objects.
    }

    public class Person : Document
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Note: The property name of the primary key field can be changed. But you'll need to specify the primary key property name when you create your table. See tableCreate for more information.

Newtonsoft DateTime Converters

Ultimately, Newtonsoft DateTime converters don't make sense when using them with RethinkDb. The reason has to do with the RethinkDb protocol requiring dates to be formatted as a specific $reql_type$ TIME type. IsoDateTimeConverter and JavaScriptDateTimeConverter should not be used as they might short-circuit the native DateTime conversions.

More in-depth information about the internal workings of the Newtonsoft serializer can be found on issues #149 and #151.