CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Collections;
using System.Dynamic;
public class Program
{
public static void Main()
{
dynamic model = ChoExpandoObject.New("performanceLevels",
new List<ChoExpandoObject>
{
ChoExpandoObject.New("performanceLevel_1",
ChoExpandoObject.New(new string[] { "title", "version", "threelevels" },
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"string", "column", "title-column", "N/A"),
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1"),
ChoExpandoObject.New("version",
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1")
)
)
),
ChoExpandoObject.New("performanceLevel_2",
new List<ChoExpandoObject>
{
ChoExpandoObject.New("title", ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"string", "column", "title-column", "N/A")
),
ChoExpandoObject.New("version", ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1")
)
}
)
}
);
var settings = new JsonSerializerSettings()
{
Converters = new List<JsonConverter> { },
Formatting = Formatting.Indented
};
var jsonMap = JsonConvert.SerializeObject(new List<ChoExpandoObject> { model }, settings);
Console.WriteLine(jsonMap);
}
/* GOAL:
[
{
"performanceLevels":[
{
"performanceLevel_1":{
"title":{
"data-type":"string",
"source":"column",
"source-column":"title-column",
"default":"N/A"
},
"version":{
"data-type":"int",
"source":"column",
"source-column":"version-column",
"default":"1"
}
}
},
{
"performanceLevel_2":{
"title":{
"data-type":"string",
"source":"column",
"source-column":"title-column",
"default":"N/A"
},
"version":{
"data-type":"int",
"source":"column",
"source-column":"version-column",
"default":"1"
}
}
}
]
}
]
*/
}
public class ChoExpandoObject : DynamicObject, IDictionary<string, object> //, IXmlSerializable
{
#region Instance Members
private readonly object _padLock = new object();
private IDictionary<string, object> _kvpDict = new Dictionary<string, object>();
#endregion Instance Members
#region Constructors
public ChoExpandoObject()
{
}
public ChoExpandoObject(IDictionary<string, object> kvpDict)
{
_kvpDict = kvpDict;
}
#endregion Constructors
#region DynamicObject Overrides
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return GetPropertyValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var key = binder.Name;
return SetPropertyValue(key, value);
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
result = null;
if ((indexes.Length == 1) && indexes[0] != null)
{
if (indexes[0] is string)
{
var key = indexes[0] as string;
return GetPropertyValue(key, out result);
}
else if (indexes[0] is int)
{
var index = (int)indexes[0];
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
result = kvpDict.ElementAt(index).Value;
return true;
}
}
return false;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if ((indexes.Length == 1) && indexes[0] != null)
{
if (indexes[0] is string)
{
var key = indexes[0] as string;
return SetPropertyValue(key, value);
}
else if (indexes[0] is int)
{
var index = (int)indexes[0];
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
kvpDict[kvpDict.ElementAt(index).Key] = value;
return true;
}
}
return true;
}
#endregion DynamicObject Overrides
#region Instance Members (Protected/Public)
protected virtual bool GetPropertyValue(string name, out object result)
{
result = null;
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
if (kvpDict.ContainsKey(name))
result = kvpDict[name];
else
{
return false;
}
}
return true;
}
protected virtual bool SetPropertyValue(string name, object value)
{
if (IsReadOnly)
return false;
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
if (!kvpDict.ContainsKey(name))
{
kvpDict.Add(name, value);
}
else
kvpDict[name] = value;
}
return true;
}
public static ChoExpandoObject New(Func<IEnumerable<KeyValuePair<string, object>>> func)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
if (func != null)
{
foreach (var kvp in func())
dict.Add(kvp.Key, kvp.Value);
}
return new ChoExpandoObject(dict);
}
public static ChoExpandoObject New(string key, object value)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add(key, value);
return new ChoExpandoObject(dict);
}
public static ChoExpandoObject New(string[] keys, params object[] values)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
if (keys != null)
{
int counter = 0;
foreach (var key in keys)
{
if (counter < values.Length)
dict.Add(key, values[counter]);
else
dict.Add(key, null);
counter++;
}
}
return new ChoExpandoObject(dict);
}
#endregion
public ICollection<string> Keys
{
get
{
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Keys : null;
}
}
public ICollection<object> Values
{
get
{
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Values : null;
}
}
public int Count
{
get
{
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Count : 0;
}
}
public bool IsReadOnly
{
get { return false; }
}
public object this[string key]
{
get
{
object result = null;
GetPropertyValue(key, out result);
return result;
}
set
{
SetPropertyValue(key, value);
}
}
public bool ContainsKey(string key)
{
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict.ContainsKey(key);
}
public void Add(string key, object value)
{
SetPropertyValue(key, value);
}
public bool Remove(string key)
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null && kvpDict.ContainsKey(key))
{
kvpDict.Remove(key);
}
return false;
}
public bool TryGetValue(string key, out object value)
{
return GetPropertyValue(key, out value);
}
public void Add(KeyValuePair<string, object> item)
{
SetPropertyValue(item.Key, item.Value);
}
public void Clear()
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
kvpDict.Clear();
}
}
public bool Contains(KeyValuePair<string, object> item)
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
return kvpDict.Contains(item);
}
return false;
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
foreach (var kvp in kvpDict)
{
array[arrayIndex++] = kvp;
}
}
}
public bool Remove(KeyValuePair<string, object> item)
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
return kvpDict.Contains(item);
}
return false;
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null)
{
foreach (var kvp in kvpDict)
{
yield return kvp;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return Keys;
}
}