2

I have a JSON string as shown below. I want to remove the empty array objects from it programmatically so that I can convert it to a DataTable.

Here is an example of my JSON:

{
   "result":[
     {
       "id":"1",
       "name": "Temp",
       "property":[]
     },
     {
       "id":"2",
       "name": "Temp2",
       "property":[]
     }
  ]
}

You can see that the property member in each result is an empty array. Any suggestion on how I can remove it?

Currently I'm doing the following to convert the JSON to a DataTable:

DataTable dt = JsonConvert.DeserializeObject<DataTable>(data["result"].ToString());

When I manually remove the array property, the conversion works perfectly.

1
  • 2
    Don't go straight to a datatable, deserialize to a custom class then convert that to a datatable (if you need to). Commented May 23, 2016 at 11:42

4 Answers 4

1

This is how you can remove 'property' array from JSON and parse the remaining data into DataTable:

foreach (var item in data["result"])
{
      JObject obj = (JObject)item;
      obj.Property("property").Remove();
}

DataTable dt = JsonConvert.DeserializeObject<DataTable>(data["result"].ToString());
Sign up to request clarification or add additional context in comments.

2 Comments

Is there an option to remove the empty array member without making a class? I'm try to create a dynamic function that can remove any empty array member, the JSON string may be different at times.
ok. I'm editing the source code according to your need. You want to remove array 'property' from json.
1

You could use a regex to remove the properties with empty arrays from the json string itself. Here is one that uses two regexes, one to kill the properties with empty arrays and the other to kill any erroneous commas that are left over.

var json = "{\"prop\": [], \"prop2\": \"test\", \"propqw\": []}";
var removeEmpty = new Regex("\\s*\"[^\"]+\":\\s*\\[\\]\\,?");
var removeComma = new Regex(",(?=\\s*})");
var result = removeEmpty.Replace(json, "");
result = removeComma.Replace(result, "");

There may be a slightly cleaner way than this but I couldn't quickly find a single regex way to remove properties and clean potential illegal commas.

2 Comments

I would not recommend using Regex for parsing/manipulating JSON. It is too error prone. Use JObjects instead.
Agree with Brian Rogers, Regex is more likely to cause future issues and there are better ways of dealing with this issue.
1

You can use Json.Net's LINQ-to-JSON API to remove the empty array properties (regardless of their names) and then convert the result to a DataTable:

JObject data = JObject.Parse(json);

var emptyArrayProperties = data["result"]
    .Children<JObject>()
    .SelectMany(jo => jo.Properties())
    .Where(jp => jp.Value.Type == JTokenType.Array && !jp.Value.HasValues)
    .ToList();

foreach (JProperty prop in emptyArrayProperties)
{
    prop.Remove();
}

DataTable table = obj["result"].ToObject<DataTable>();

Fiddle: https://dotnetfiddle.net/rVIijq

Comments

1

To move straight to the point with reference to the above issue, we could resolve that using IContractResolver which works as follows:

  1. Create a class in your project model folder, for instance MyClass.
  2. add the following code

    public class MyClass : DefaultContractResolver
    {
    
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
            property.ShouldSerialize = obj =>
            {
                if (property.PropertyType.Name.Contains("ICollection"))
                {
                    return (property.ValueProvider.GetValue(obj) as dynamic).Count > 0;
                }
                return true;
            };
            return property;
        }
    }
    
  3. DefaultContractResolver comes from the Newtonsoft.Json.Serialization so you need to install Newtonsoft.Json from nuget package manager and add * using Newtonsoft.Json * and * using Newtonsoft.Json.Serialization; * to MyClass.cs file we created.

    1. CreateProperty and MemberInfo comes from System.Reflection; so add * using System.Reflection; * in order to import them.

    2. We want to make it accessible across the project domain so we will instantiate the class in the Global.asax file, so locate and open the Global.asax and add the following to the protected void Application_Start() method.

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented;
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new MyClass();
    GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
    

    NB: make sure to add * using Newtonsoft.Json; * and * using YourProjectName.Models; * in your Global.asax file

Voila!!!.... You may run your project to see the outcome.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.