36

I have a bunch of classes that will be serialized to JSON at some point and for the sake of following both C# conventions on the back-end and JavaScript conventions on the front-end, I've been defining properties like this:

[JsonProperty(PropertyName="myFoo")]
public int MyFoo { get; set; }

So that in C# I can:

MyFoo = 10;

And in Javascript I can:

if (myFoo === 10)

But doing this for every property is tedious. Is there a quick and easy way to set the default way JSON.Net handles property names so it will automatically camel case unless told otherwise?

Matt Burland
  • 44,552
  • 18
  • 99
  • 171

8 Answers8

42

You can use the provided class Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver:

var serializer = new JsonSerializer
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jobj = JObject.FromObject(request, serializer);

In other words, you don't have to create a custom resolver yourself.

Big McLargeHuge
  • 14,841
  • 10
  • 80
  • 108
  • `CamelCasePropertyNamesContractResolver` has actually been around for a long time. It was present at least as far back as [Json.Net 4.0.2](https://github.com/JamesNK/Newtonsoft.Json/releases/tag/4.0.2) (released Apr 21, 2011). If you notice, the OP's resolver even inherits from it. – Brian Rogers Oct 16 '15 at 22:26
  • By OP I assume you mean the person who asked the question. There's no mention of it there. Good catch though. – Big McLargeHuge Oct 16 '15 at 22:48
  • 4
    Is it possible to specify the resolver as an attribute of the class? – boggy Oct 31 '17 at 19:12
19

When serializing your object, pass in some custom settings.

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var json = JsonConvert.SerializeObject(yourObject, settings);
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
10

Better to use the new CamelCaseNamingStrategy (since 9.0.1):

new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver
    {
       NamingStrategy = new CamelCaseNamingStrategy()
    }
};

It does not override custom names set by attribute JsonProperty("Name") by default. (You can change the behaviour by CamelCaseNamingStrategy(bool, bool) ctor.) So, does not need to create custom class like @Matt Burland's answer.

AnGG
  • 679
  • 3
  • 9
xmedeko
  • 7,336
  • 6
  • 55
  • 85
  • Do you happen to know which is the first Newtonsoft.Json version to contain CamelCaseNamingStrategy? – vezenkov Oct 31 '19 at 10:19
  • 1
    @vezenkov since [9.0.1](https://github.com/JamesNK/Newtonsoft.Json/releases/tag/9.0.1) according to the changelog. – xmedeko Oct 31 '19 at 12:25
9

JObject.FromObject uses default settings from JsonConvert defaults. There is a func property that you can assign like this:

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
 {
   ContractResolver = new CamelCasePropertyNamesContractResolver()
 };

and whenever you call Jobject.FromObject, it will use this func to construct settings.

7

Since the accepted answer is link-only, I'm adding the actual code I ended up using (in case the link dies). It's largely the same as what was in the link:

// Automatic camel casing because I'm bored of putting [JsonProperty] on everything
// See: http://harald-muehlhoff.de/post/2013/05/10/Automatic-camelCase-naming-with-JsonNET-and-Microsoft-Web-API.aspx#.Uv43fvldWCl
public 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 && attr.PropertyName != null)
                res.PropertyName = attr.PropertyName;
        }

        return res;
    }
}

The only change I made was the addition of attr.PropertyName != null to the if clause because of the case where I had added something like:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string SomeProperty { get; set; }

And didn't want to specify the PropertyName (so it's null). The above will be serialized in JSON as someProperty.

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
6

You can use a custom contract resolver:

class MyContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);

        foreach (var property in properties)
        {
            property.PropertyName = char.ToLower(property.PropertyName[0]) + string.Join("", property.PropertyName.Skip(1));
        }

        return properties;
    }
}

And use it like:

class MyClass
{
    public int MyProperty { get; set; }
    public int MyProperty2 { get; set; }
}

var json = JsonConvert.SerializeObject(new MyClass(), 
                Formatting.Indented, 
                new JsonSerializerSettings { ContractResolver = new MyContractResolver() });
Alberto
  • 15,626
  • 9
  • 43
  • 56
2

In .NET 5.0 you can use System.Text.Json and specifiy the ProperyNamingPolicy inside the JsonSerializerOptions

System.Text.Json.JsonSerializerOptions.PropertyNamingPolicy

Here's a link to the Microsoft docs page on setting the property to use camel case.

var serializeOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);

Class

public class WeatherForecastWithPropertyNameAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
    [JsonPropertyName("Wind")]
    public int WindSpeed { get; set; }
}

JSON output

{
  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
  "Wind": 35
}
JCH
  • 170
  • 11
-1
public static JsonSerializer FormattingData()
{
   var jsonSerializersettings = new JsonSerializer {
   ContractResolver = new CamelCasePropertyNamesContractResolver() };
   return jsonSerializersettings;
}


public static JObject CamelCaseData(JObject jObject) 
{   
     var expandoConverter = new ExpandoObjectConverter();
     dynamic camelCaseData = 
     JsonConvert.DeserializeObject(jObject.ToString(), 
     expandoConverter); 
     return JObject.FromObject(camelCaseData, FormattingData());
}
rafiq J
  • 1
  • 5