How to apply indenting serialization only to some properties?
.net, c#, json, json.net, serialization
Solution
One possibility would be to write a custom Json converter for the specific types you need special handling and switch the formatting for them:
class Program
{
static void Main()
{
var root = new Root
{
Array = new[] { "element 1", "element 2", "element 3" },
Object = new Obj
{
Property1 = "value1",
Property2 = "value2",
},
};
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
};
settings.Converters.Add(new MyConverter());
string json = JsonConvert.SerializeObject(root, settings);
Console.WriteLine(json);
}
}
public class Root
{
public string[] Array { get; set; }
public Obj Object { get; set; }
}
public class Obj
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
class MyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string[]) || objectType == typeof(Obj);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue(JsonConvert.SerializeObject(value, Formatting.None));
}
}
This will output:
{
"Array": ["element 1","element 2","element 3"],
"Object": {"Property1":"value1","Property2":"value2"}
}
Problem
I want to serialize .NET objects to JSON in a human-readable way, but I would like to have more control about whether an object's properties or array's elements end up on a line of their own. Currently I'm using JSON.NET's `JsonConvert.SerializeObject(object, Formatting, JsonSerializerSettings)` method for serialization, but it seems I can only apply the `Formatting.Indented` (all elements on individual lines) or `Formatting.None` (everything on a single line without any whitespace) formatting rules globally for the entire object. Is there a way to globally use indenting by default, but turn it off for certain classes or properties, e.g. using attributes or other parameters? To help you understand the problem, here are some output examples. Using `Formatting.None`: ``` {"array":["element 1","element 2","element 3"],"object":{"property1":"value1","property2":"value2"}} ``` Using `Formatting.Indented`: ``` { "array": [ "element 1", "element 2", "element 3" ], "object": { "property1": "value1", "property2":"value2" } } ``` What I would like to see: ``` { "array": ["element 1","element 2","element 3"], "object": {"property1":"value1","property2":"value2"} } ``` (I realize my question may be slightly related to this one, but the comments there totally miss the point and don't actually provide a valid answer.)