RDS RDS - 13 days ago 5
C# Question

C# JSON.net null nested objects

I am parsing some JSON to csv. I have my class setup as follows:

public class SearchObj
{
public class Property
{
public string __cloudera_internal__hueLink { get; set; }
}
public class root
{
public string blockSize { get; set; }
public string clusteredByColNames { get; set; }
public string compressed { get; set; }
public string created { get; set; }
public string dataType { get; set; }
public string deleted { get; set; }
public Property properties { get; set; }
}
}


then later on I work with this object:

string json = infile.ReadToEnd();
var rootObject = JsonConvert.DeserializeObject<List<SearchObj.root>>(json);
for (int i = 0; i < rootObject.Count; i++)
{
//holding is a dict that holds json key/value pairs,
//arg[1] is a prefix for key:value pairs, in this case, no prefix
//so a nested key goes into dictionary as key.nestedkey
ResolveTypeAndValue(rootObject[i], "", holding);
}


And of course we need to see the code for the Resolve method:

private static void ResolveTypeAndValue(object obj, string name, Dictionary<string, string> storage)
{
//this next line is the error problem
var type = obj.GetType();
foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
if (p.PropertyType.IsClass && p.PropertyType != typeof(string))
{
var currentObj = p.GetValue(obj);
ResolveTypeAndValue(currentObj, p.Name + ".", storage);
}
else
{
string val = "";
if (p.GetValue(obj) != null)
{
val = p.GetValue(obj).ToString();
}
storage.Add(name + p.Name, val);
}
}
}


So when I run this I get a "An unhandled exception of type 'System.NullReferenceException' occurred in....." tagging the above line. I believe it is because most of the time, the "properties" key is null. In fact the "properites" key, despite being nested only has a single key:value pair of the "__cloudera_internal__hueLink " as the key and a html address (essentially text) as the value.

I ran this code successfully on a different set of JSON schema with no issues--but for the life of me, I cannot figure out how to basically set the key/value pair to something like "properties":"null" or "properties.__cloudera_internal__hueLink ":"the value field". previously the nested json object always had something in it, even if it varied from entry to entry.

You'll probably need to help at a newcomer level, I only use C# at work as it is all I have available--but obviously I have picked up a thing or two along here at SO about dealing with JSON objects, but this one has me stuck pretty hard

I either get the errors or the "properties" is not populated at all and throws a key not found error

Answer

Change the ResolveTypeAndValue function to this:

private static void ResolveTypeAndValue(object obj, string name, Dictionary<string, string> storage)
{
    if (obj == null)
    {
        storage.Add(name, null);
        return;
    }

    var type = obj.GetType();
    foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
    {
        if (p.PropertyType.IsClass && p.PropertyType != typeof(string))
        {
            var currentObj = p.GetValue(obj);
            ResolveTypeAndValue(currentObj, p.Name, storage); // removed this: '+ "."'
        }
        else
        {
            string val = "";
            if (p.GetValue(obj) != null)
            {
                val = p.GetValue(obj).ToString();
            }
            storage.Add(name + "." + p.Name, val); // added this: '+ "."'
        }
    }
}
Comments