3

With JSON.Net, I see 2 different ways of saying that I want my properties to be serialized in camelCase:

According to this code snippet, both options give the same result since the assertion does not fail:

public class Bar
{
    public int SomeValue { get; set; }
}

public class Foo
{
    public Bar Bar { get; set; } = new Bar();
    public string AnotherValue { get; set; }
}

[Fact]
public void TestBothOptions()
{
    var x = new Foo();
    x.AnotherValue = "test";
    x.Bar.SomeValue = 12;

    var serializerSettingsWithNamingStrategy = new JsonSerializerSettings();
    serializerSettingsWithNamingStrategy.ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new CamelCaseNamingStrategy(),
    };

    var serializerSettingsWithContractResolver = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
    };


    var one = JsonConvert.SerializeObject(x, serializerSettingsWithNamingStrategy);
    var two = JsonConvert.SerializeObject(x, serializerSettingsWithContractResolver);

    Assert.Equal(one, two); // {"bar":{"someValue":12},"anotherValue":"test"}
}

So, does anybody know the difference between the two options?

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
mabead
  • 2,171
  • 2
  • 27
  • 42

1 Answers1

3

CamelCaseNamingStrategy is newer and more flexible to use, since you can specify, via attributes, different naming strategies to use for different classes or properties in your model without using a resolver, e.g.:

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class MyClass
{
    public string CamelCaseProperty1 { get; set; }

    public string CamelCaseProperty2 { get; set; }

    [JsonProperty(NamingStrategyType = typeof(DefaultNamingStrategy)]
    public string DefaultCaseProperty { get; set; }  
}

You can also create your own custom naming strategy class if you need to.

CamelCasePropertyNamesContractResolver still survives for backward compatibility. After CamelCaseNamingStrategy was introduced, the source code for that resolver was changed to use the strategy. You can see this clearly in this excerpt from the source code:

public class CamelCasePropertyNamesContractResolver : DefaultContractResolver
{
    ...

    public CamelCasePropertyNamesContractResolver()
    {
        NamingStrategy = new CamelCaseNamingStrategy
        {
            ProcessDictionaryKeys = true,
            OverrideSpecifiedNames = true
        };
    }

    ...
}

Note there are subtle differences between the CamelCasePropertyNamesContractResolver and the DefaultContractResolver in terms of how they cache information, which may or may not be of concern to you. See Does Json.NET cache types' serialization information? for more information about that.

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300