19

I'm using Json.Net for my website. I want the serializer to serialize property names in camelcase by default. I don't want it to change property names that I manually assign. I have the following code:

public class TestClass
{
    public string NormalProperty { get; set; }

    [JsonProperty(PropertyName = "CustomName")]
    public string ConfiguredProperty { get; set; }
}

public void Experiment()
{
    var data = new TestClass { NormalProperty = null, 
        ConfiguredProperty = null };

    var result = JsonConvert.SerializeObject(data,
        Formatting.None,
        new JsonSerializerSettings {ContractResolver
            = new CamelCasePropertyNamesContractResolver()}
        );
    Console.Write(result);
}

The output from Experiment is:

{"normalProperty":null,"customName":null}

However, I want the output to be:

{"normalProperty":null,"CustomName":null}

Is this possible to achieve?

Oliver
  • 11,297
  • 18
  • 71
  • 121
  • don't use `CamelCasePropertyNamesContractResolver` and use `JsonProperty` only. – L.B Oct 05 '12 at 15:26
  • @L.B If I only use JsonProperty, the default naming will be PascalCase, so `normalProperty` will instead be `NormalProperty` in the JSON. – Oliver Oct 05 '12 at 16:53
  • Oliver No, It is serialized exactly as what you give in JsonProperty. – L.B Oct 05 '12 at 16:58
  • 1
    @L.B If there is no JsonProperty, it is serialized as `NormalProperty`. If I need to serialize a class that has 20 PascalCase properties, I don't want to have to write a `JsonProperty` for each of them to meet javascript naming conventions. It is needless effort. – Oliver Oct 05 '12 at 19:43
  • 1
    The code above works for me without any modifications using version 7.0.1 of Newtonsoft.Json, so I think this may have been a bug that was fixed. – Big McLargeHuge Oct 16 '15 at 18:41

2 Answers2

21

You can override the CamelCasePropertyNamesContractResolver class like this:

class CamelCase : CamelCasePropertyNamesContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member,
        MemberSerialization memberSerialization)
    {
        var res = base.CreateProperty(member, memberSerialization);

        var attrs = member
            .GetCustomAttributes(typeof(JsonPropertyAttribute),true);
        if (attrs.Any())
        {
            var attr = (attrs[0] as JsonPropertyAttribute);
            if (res.PropertyName != null)
                res.PropertyName = attr.PropertyName;
        }

        return res;
    }
}
Oliver
  • 11,297
  • 18
  • 71
  • 121
  • 8
    One slight improvement `if (res.PropertyName != null && attr.PropertyName != null)` Doing this allows you to set a `JsonProperty` attribute on a field without a name and still have it handled with regular camel casing. Useful if you want to just set something like `[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]` – Matt Burland Sep 18 '14 at 18:20
2

With the introduction of NamingStrategy it's easier.
As a bonus you can get it to not modify dictionary keys.

class MyContractResolver : CamelCasePropertyNamesContractResolver
{
    public MyContractResolver()
    {
        NamingStrategy.OverrideSpecifiedNames = false;    //Overriden
        NamingStrategy.ProcessDictionaryKeys = false;     //Overriden
        NamingStrategy.ProcessExtensionDataNames = false; //default
    }
}
hultqvist
  • 17,451
  • 15
  • 64
  • 101