1

We are serialising an object to JSON which has a property that is an array of dynamic objects, e.g.:

public List<dynamic> Widgets { get; set; }
public string Name {get;set;}

The serialisation is set to use the built in camel case resolver, with the option ProcessDictionaryKeys set to true, as per advice from this post :

var contractResolver = new CamelCasePropertyNamesContractResolver();
contractResolver.NamingStrategy.ProcessDictionaryKeys = true;

jsonSerializerSettings.ContractResolver = contractResolver;

However the resultant JSON retains the pascal case (which is how the objects are stored in the database) for the entries in this field. All other properties get converted to camel case as expected.

Example output for the above:

{
 name:"test",
 widgets:[{Name:"Widget1",Description:"A nice widget"}]
}

So why does the naming strategy only apply to strongly typed C# objects and not these dynamic values?

I have verified the obvious things, i.e. ensured the serialisation settings are being applied.

Jon Eastwood
  • 813
  • 10
  • 22
  • How us `List Widgets` initialized? `dynamic` is a keyword [*used to tell the compiler that a variable's type can change or that it is not known until runtime*](https://stackoverflow.com/a/2690661). Thus any c# object can be added to a `List`, such as a regular POCO, a `Dictionary`, an `ExpandoObject`, a `JObject`, or anything else. `ProcessDictionaryKeys` should only applies if the object is, in fact, a dictionary. – dbc Jan 18 '19 at 19:12
  • Can't reproduce using an actual `Dictionary` in the `List`, see https://dotnetfiddle.net/Plvws8. Can you please share a [mcve]? – dbc Jan 18 '19 at 19:16
  • Can't reproduce with an `ExpandoObject` either, see also https://dotnetfiddle.net/Plvws8 – dbc Jan 18 '19 at 19:26
  • But if your `dynamic` object is a `JObject` then the contract resolver does not apply, see [JObject & CamelCase conversion with JSON.Net](https://stackoverflow.com/q/15087340) and [How to Capitalize initial letters to lowercase? #1501](https://github.com/JamesNK/Newtonsoft.Json/issues/1501#issuecomment-345490252). – dbc Jan 18 '19 at 19:35
  • Good point - yes I think it may be a Jobject. It is instantiated by json.net when the object is loaded from the database – Jon Eastwood Jan 20 '19 at 08:57
  • If it is a `JObject` then see [this answer](https://stackoverflow.com/a/11681449) to [Json.net rename properties](https://stackoverflow.com/q/11679804). For the `Func map` you would pass in something like `name => new CamelCaseNamingStrategy().ResolvePropertyName(name)` (though you could cache the strategy to avoid adding too much memory pressure). Agree this is a duplicate of that question and [JObject & CamelCase conversion with JSON.Net](https://stackoverflow.com/q/15087340)? Or do you need a specific answer? If so a [mcve] would help. – dbc Jan 22 '19 at 06:17

1 Answers1

0

Thanks to dbc for the help.

In case anyone else has the issue, the problem was that the underlying object was a JObject - for some reason I assumed it would be an ExpandoObject.

JSON.net will not respect the naming conventions for JObjects, they are serialised as-is so you must come up with some solution to manually convert the object keys.

I chose a custom object converter, as per this post: How to serialize a JObject the same way as an object with Json.NET?

Jon Eastwood
  • 813
  • 10
  • 22