ITypeSerializer replaces JsonSerializerSettings


#1

according to the documentation of the 2.1.1.0 .NET sdk, the property of SerializationSettings.ContractResolver under configuration is obsolete:
"Please use a custom ITypeSerializer instead; this property is no longer used will be removed in a future release. See NCBC-676 for details."
however, i couldn’t find a way to use ITypeSerializer to replace the two lines:

_cluster.Configuration.SerializationSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
            _cluster.Configuration.DeserializationSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();

How should I write these lines using the new ITypeSerializer ?


#2

This post shows an example of the “new” way to do this with an ITypeSerializer: Custom converter not used

-Jeff


#3

thanks!
The thing is that we are using the setting which are in the web.config
Thus, I tried to edit the configuration accordingly:

        ClusterHelper.Initialize("couchbaseClients/couchbase");
        _cluster = ClusterHelper.Get();
        _cluster.Configuration.Serializer = () =>
        {
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
            serializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();

            return new DefaultSerializer(serializerSettings, serializerSettings);
        };

however, running the code, still the result was in camelCase.
Seems like changing the serializer has no effect (especially when the obsolete SerializationSettings.ContractResolver seems to be still configured in camelCase).
Please suggest.


#4

Hi @mashav,
The ordering of the init code is very important and only run ones.
That means that you have to choose to do all configuration in the app.config/web.config file or do all configuration in code. There is no way to mix the two options.

This is how you could initialize from pure code:

var config = new ClientConfiguration
        {
            Servers = new List<Uri>
                    {
                        new Uri("http://localhost:8091/pools"),
                    }
            ,
            UseSsl = false
            ,
            BucketConfigs = new Dictionary<string, BucketConfiguration>
                        {
                            {
                                "default", 
                                new BucketConfiguration
                                {
                                    BucketName = "default",
                                    UseSsl = false,
                                    Password = "",
                                    PoolConfiguration = new PoolConfiguration
                                        {
                                            MaxSize = 5,
                                            MinSize = 1
                                        }
                                }
                            }
                        }
        };
        config.Serializer = () =>
        {
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
            serializerSettings.ContractResolver = new CustomContractResolver();

            return new Couchbase.Core.Serialization.DefaultSerializer(serializerSettings, serializerSettings);
        };

        ClusterHelper.Initialize(config);

#5

and using config files only:

  <couchbase_2>
  <servers>
    <add uri="http://localhost:8091"></add>
    <add uri="http://localhost2:8091"></add>
   </servers>
  <buckets>
    <add name="default" useSsl="true"></add>
  </buckets>
  <converter name="fakeConverter" type="Couchbase.Tests.Fakes.FakeConverter, Couchbase.Tests" />
  <transcoder name="fakeTranscoder" type="Couchbase.Tests.Fakes.FakeTranscoder, Couchbase.Tests" />
  <serializer name="fakeSerializer" type="Couchbase.Tests.Fakes.FakeSerializer, Couchbase.Tests" />
</couchbase_2>

#6

Thanks for the explanation and the examples, @martinesmann

let me see it I got it right:
I can either have the configuration hardcoded, then I’ll have to redeploy the code for every change of configuration.
Then I just add these lines for the configuration constructor:

Serializer = () =>
            {
                JsonSerializerSettings serializerSettings = new JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver() };

                return new DefaultSerializer(serializerSettings, serializerSettings);
            }

or I can add it to the web.config with the serializer tag, and then I’ll have to implement the ITypeSerializer interface, just in order not to use camelCase for the properties names?
or is there a simpler way?


#7

@mashav -

The other option is to simply inherit from DefaultSerializer and call the base CTORs, passing in your new serializer settings. Something like this:

public class CustomSerializer : DefaultSerializer
{
    public CustomSerializer() : base(new JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver() }, 
    new JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver() })
    {
    }
} 

And then use the serializer element in the config:

<serializer name="CustomSerializer" type="YourNamspace.CustomSerializer, YourAssemblyName" />

That being said, you can always create a feature request in Jira to make the CTOR parameters configurable in the config:

<serializer name="fakeSerializer" type="Couchbase.Tests.Fakes.FakeSerializer, Couchbase.Tests" >
    <parameters>
        <param name="deserializationSettings" type=".."/>
        ...
    </parameters>
</serializer>

You could also trying implementing the feature yourself if you feel inclined and need it ASAP. If you do please submit a pull request :smile:

-Jeff


#8

thanks @jmorris!
I’ll add it to my to do list, but cannot promise anything :confused:

I really like your solution, elegantly use of inheritance.
Going to use it. Thanks!