1

I am attempting to use the Newtonsoft JSON library to parse a JSON string dynamically using C#. In the JSON is a named array. I would like to remove the square brackets from this array and then write out the modified JSON.

The JSON now looks like the following. I would like to remove the square bracket from the ProductDescription array.

{
    "Product": "123",
    "to_Description": [
        {
            "ProductDescription": "Product 1"
        }
    ]
} 

Desired result

{
    "Product": "123",
    "to_Description": 
        {
            "ProductDescription": "Product 1"
        }
}

I believe I can use the code below to parse the JSON. I just need some help with making the modification.

JObject o1 = JObject.Parse(File.ReadAllText(@"output.json"));
1
  • So you're saying that the array always contains 1 object, and you want to move the object out of the array and for it to replace the array, so that you only have that 1 object as the value? You know that there will always be 1 object in the array? Not 0? Not 2? Not more? Commented Sep 17, 2019 at 7:10

4 Answers 4

1

The to_Description property starts off as List<Dictionary<string,string>> and you want to take the first element from the List.

So, given 2 classes

public class Source
{
   public string Product {get;set;}
   public List<Dictionary<string,string>> To_Description{get;set;}
}


public class Destination
{
   public string Product {get;set;}
   public Dictionary<string,string> To_Description{get;set;}
}

You could do it like this:

var src = JsonConvert.DeserializeObject<Source>(jsonString);
var dest = new Destination
{
    Product = src.Product,
    To_Description = src.To_Description[0]
};
var newJson = JsonConvert.SerializeObject(dest);

Note: You might want to check there really is just 1 item in the list!

Live example: https://dotnetfiddle.net/vxqumd

Sign up to request clarification or add additional context in comments.

Comments

0

You do not need to create classes for this task. You can modify your object like this:

// Load the JSON from a file into a JObject
JObject o1 = JObject.Parse(File.ReadAllText(@"output.json"));

// Get the desired property whose value is to be replaced
var prop = o1.Property("to_Description");

// Replace the property value with the first child JObject of the existing value
prop.Value = prop.Value.Children<JObject>().FirstOrDefault();

// write the changed JSON back to the original file
File.WriteAllText(@"output.json", o1.ToString());

Fiddle: https://dotnetfiddle.net/M83zv3

Comments

0

I have used json2csharp to convert the actual and desired output to classes and manipulated the input json.. this will help in the maintenance in future

First defined the model

    public class ToDescription
    {
        public string ProductDescription { get; set; }
    }

    public class ActualObject
    {
        public string Product { get; set; }
        public List<ToDescription> to_Description { get; set; }
    }

    public class ChangedObject
    {
        public string Product { get; set; }
        public ToDescription to_Description { get; set; }
    }

Inject the logic

    static void Main(string[] args)
    {
        string json = "{\"Product\": \"123\",  \"to_Description\": [     {        \"ProductDescription\": \"Product 1\"    }  ]} ";

        ActualObject actualObject = JsonConvert.DeserializeObject<ActualObject>(json);
        ChangedObject changedObject = new ChangedObject();
        changedObject.Product = actualObject.Product;
        changedObject.to_Description = actualObject.to_Description[0];
        string formattedjson = JsonConvert.SerializeObject(changedObject);
        Console.WriteLine(formattedjson);
    }

Comments

0

Why not:

public class EntityDescription 
{
  public string ProductDescription { get; set; }
}

public class Entity
{
   public string Product { get; set; }
}

public class Source : Entity 
{
   [JsonProperty("to_Description")]
   public EntityDescription[] Description { get; set; }
}

public class Target : Entity 
{
   [JsonProperty("to_Description")]
   public EntityDescription Description { get; set; }
}

var raw = File.ReadAllText(@"output.json");
var source = JsonConvert.DeserializeObject<Source>(raw);
var target = new Target { Product = source.Product, Description = source.Description.FirstOrDefault() };
var rawResult = JsonConvert.SerializeObject(target);

Update For dynamic JSON

var jObject = JObject.Parse(File.ReadAllText(@"output.json"));
var newjObject = new JObject();
foreach(var jToken in jObject) {
  if(jToken.Value is JArray) {
    List<JToken> l = jToken.Value.ToObject<List<JToken>>();
      if(l != null && l.Count > 0) {
          newjObject.Add(jToken.Key, l.First());    
             }
       } else {
          newjObject.Add(jToken.Key, jToken.Value);
       }
    }

   var newTxt = newjObject.ToString();

1 Comment

Thanks for the responses. There will only be one object in the array. Apologies, but I didn't mention that the code needs to be dynamic. I want to read in the JSON and pass in any array to be converted, not just the one I had provided as an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.