0

I am using Newtonsoft.Json for JSon serialize and De-serialize. I am having issue with List of object element with indent. My problem is I want to display 10 element in one row then again 10 elements and rest will in 3rd row. How it can be possible with JToken?

Below is my expected output.

 "parameters": [
      {           
        "description": "EnableTestValues",
        "defaults": [
          0,1,1,2,3,4,5,6,9,7,
          99,12,85,14,66,78
        ],
        "size": [
          1,16
        ]
      },
      {            
        "description": "CEC_Emer_Stop_Val",
        "defaults": [
          false
        ],
        "size": [
          1,1
        ]
      },
      {            
        "description": "CEC_Emer_Stop_Sw",
        "defaults": [
          252
        ],
        "size": [
          1,1
        ]
      }          
    ]

But I am getting

"parameters": [
      {           
        "description": "EnableTestValues",
        "defaults": [
          0,
          1,
          1,
          2,
          3,
          4,
          5,
          6,
          9,
          7,
          99,
          12,
          85,
          14,
          66,
          78
        ],
        "size": [
          1,
          16
        ]
      },
      {            
        "description": "CEC_Emer_Stop_Val",
        "defaults": [
          false
        ],
        "size": [
          1,
          1
        ]
      },
      {            
        "description": "CEC_Emer_Stop_Sw",
        "defaults": [
          252
        ],
        "size": [
          1,
          1
        ]
      }          
    ]

Issue is with default and size property.

For serialize and de-serialize I am using dynamic object. Code is as below:

 dynamic mdcsJson;
            using (StreamReader r = new StreamReader(mdcsJsonFilePath))
            {
                string fileContent = System.IO.File.ReadAllText(mdcsJsonFilePath, Encoding.GetEncoding(1250));
                mdcsJson = JsonConvert.DeserializeObject(fileContent);
            }
 // Updating some values here
string strJson = JsonConvert.SerializeObject(mdcsJson)
Srusti Thakkar
  • 1,835
  • 2
  • 22
  • 52
  • Json.NET strips whitespace & indenting when reading/deserializing. If you want to preserve whitespace when deserializing, the only option I know of is `JsonDocument` from System.Text.Json. But if you only want to disable indenting when serializing arrays see [Creating JSON without array indentation](https://stackoverflow.com/q/53223517) or [Newtonsoft inline formatting for subelement while serializing](https://stackoverflow.com/q/30831895/3744182). – dbc Dec 16 '22 at 05:28
  • Or wait, does [JObject tostring formatting issue for JArray](https://stackoverflow.com/q/65304693/3744182) answer your question? It's almost what you need, absent the newline for every 10 array elements. – dbc Dec 16 '22 at 05:42
  • Any how possible for 10 array element? – Srusti Thakkar Dec 16 '22 at 06:06
  • @dbc, Any other way for this? – Srusti Thakkar Dec 16 '22 at 09:48

1 Answers1

-1

Use Custom JsonConverter.

public class FormatArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsArray;
    }

    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        var values = (value as Array).OfType<object>().ToArray();

        writer.WriteStartArray();
        writer.WriteRawValue(""); // makes a line break

        if (values.All(x => x.GetType().IsPrimitive))
        {
            foreach (var chunk in values.Chunk(10))
            {
                writer.WriteRaw(string.Join(",", chunk));

                if (chunk.Length == 10)
                    writer.WriteRawValue(""); // makes a line break
            }
        }
        else
        {
            foreach (var item in values)
                serializer.Serialize(writer, item);
        }
        writer.WriteEndArray();
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Models:

public class Root
{
    public Parameter[] parameters { get; set; }
}

public class Parameter
{
    public string description { get; set; }
    public object[] defaults { get; set; }
    public int[] size { get; set; }
}

Data:

var root = new Root
{
    parameters = new Parameter[]
    {
        new Parameter
        {
            description = "EnableTestValues",
            defaults = new object[] { 0,1,1,2,3,4,5,6,9,7,99,12,85,14,66,78 },
            size = new int[] { 1,16 }
        },
        new Parameter
        {
            description = "CEC_Emer_Stop_Val",
            defaults = new object[] { false },
            size = new int[] { 1,1 }
        },
        new Parameter
        {
            description = "CEC_Emer_Stop_Sw",
            defaults = new object[] { 252 },
            size = new int[] { 1,1 }
        },
    }
};

Use:

var converter = new FormatArrayConverter();
string json = JsonConvert.SerializeObject(root, Formatting.Indented, converter);
Console.WriteLine(json);
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • This is not working with JObject. – Srusti Thakkar Dec 19 '22 at 05:48
  • @SrustiThakkar - The code in your question does not contain a JObject. / Why did you mention JObject at all? You either use (de)serialization, or you use JObject. Don't mix different APIs to work with JSON. – Alexander Petrov Dec 20 '22 at 18:37
  • I just want serialize and deserialize json and update some value. It will be either dynamic or JObject whatever it is. My requirement is 10 elements in one row. Can you tell me how that can be possible? It doesn't matter whatever is the object type while I am deserialing the Json. – Srusti Thakkar Dec 21 '22 at 05:10
  • I had already mention in my code that I am using dynamic instead of any call while deserialize the json. So your code `return objectType.IsArray;` is not satisfying any property of my object. – Srusti Thakkar Dec 21 '22 at 05:12
  • The main reason is I am not using any model class so while desrialize it will not identify that array is there or not. – Srusti Thakkar Jan 03 '23 at 07:18