Your JSON consists of a root object that contains a "items"
property that has an array of objects with both standard and variable properties. You need to capture all the property names and values in each item without knowing them in advance.
You've tagged your question json.net so I'll answer in c#. You have a couple of options.
Use [JsonExtensionData]
Json.NET supports deserialization and re-serialization of arbitrary JSON properties into a POCO by adding [JsonExtensionData]
to a dictionary of custom property name/value pairs:
public class Item
{
public Item() { this.CustomFields = new Dictionary<string, JToken>(); }
public string flowState { get; set; }
public long id { get; set; }
public Guid uid { get; set; }
[JsonExtensionData]
public IDictionary<string, JToken> CustomFields { get; private set; }
}
public class RootObject
{
public RootObject() { this.items = new List<Item>(); }
public Guid application_uid { get; set; }
public string formId { get; set; }
public int recordCount { get; set; }
public List<Item> items { get; set; }
}
Then you can loop through the names and values of the custom properties as follows:
var root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (var item in root.items)
{
Console.WriteLine(string.Format("Showing custom properties for Item id {0}, uid {1}, flowState {2}", item.id, item.uid, item.flowState));
{
foreach (var field in item.CustomFields)
{
Console.WriteLine(string.Format(" Field: \"{0}\": Value: \"{1}\"", field.Key, field.Value.ToString(Formatting.None)));
}
Console.WriteLine("");
}
}
Prototype fiddle.
Use ExpandoObject
Json.NET directly supports deserializing to ExpandoObject
so you could use this class for your item:
public class RootObject
{
public RootObject() { this.items = new List<ExpandoObject>(); }
public Guid application_uid { get; set; }
public string formId { get; set; }
public int recordCount { get; set; }
public List<ExpandoObject> items { get; set; }
}
Then do:
var root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (var item in root.items)
{
Console.WriteLine(string.Format("Showing custom properties for Item id {0}, uid {1}, flowState \"{2}\":",
item.AsDynamic().id, item.AsDynamic().uid, item.AsDynamic().flowState));
{
foreach (var field in item.AsDictionary())
{
if (field.Key == "id" || field.Key == "uid" || field.Key == "flowState")
continue;
Console.WriteLine(string.Format(" - Field: \"{0}\":\n Value: {1}", field.Key, JsonConvert.SerializeObject(field.Value)));
}
Console.WriteLine("");
}
}
With the following extension methods:
public static class DictionaryExtensions
{
public static IDictionary<TKey, TValue> AsDictionary<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
return dictionary;
}
}
public static class DynamicExtensions
{
public static dynamic AsDynamic(this IDynamicMetaObjectProvider obj)
{
return obj;
}
}
Prototype fiddle.
This removes the direct dependency on Json.NET from your models. However, unlike the first solution, ExpandoObject
is sealed so cannot be subclassed to add your standard three properties.