Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Okay, I'm redoing my answer based on the feedback. The dynamic object generator code still comes from this:</p> <p><a href="https://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object">Deserialize JSON into C# dynamic object?</a></p> <p>This uses RegEx, Generic collections and it does use Linq, but only in 2 lines and those can easily rewritten to not use Linq (the two 'result = ' lines at the end of <code>DynamicJsonObject.TryGetMember()</code>). The generic dictionaries can also be replaced with hash tables if necessary.</p> <p>The json parser is adapted from <a href="https://stackoverflow.com/questions/1207731/how-can-i-deserialize-json-to-a-simple-dictionarystring-string-in-asp-net">How can I deserialize JSON to a simple Dictionary&lt;string,string&gt; in ASP.NET?</a></p> <pre><code>class Program { static void Main(string[] args) { string data = "{ 'test': 42, 'test2': 'test2\"', 'structure' : { 'field1': 'field1', 'field2': 44 } }"; dynamic x = new DynamicJsonObject(JsonMaker.ParseJSON(data)); Console.WriteLine(x.test2); Console.WriteLine(x.structure.field1); Console.ReadLine(); } } public class DynamicJsonObject : DynamicObject { private readonly IDictionary&lt;string, object&gt; _dictionary; public DynamicJsonObject(IDictionary&lt;string, object&gt; dictionary) { if (dictionary == null) throw new ArgumentNullException("dictionary"); _dictionary = dictionary; } public override string ToString() { var sb = new StringBuilder(); ToString(sb); return sb.ToString(); } private void ToString(StringBuilder sb) { sb.Append("{"); var firstInDictionary = true; foreach (var pair in _dictionary) { if (!firstInDictionary) sb.Append(","); firstInDictionary = false; var value = pair.Value; var name = pair.Key; if (value is string) { sb.AppendFormat("\"{0}\":\"{1}\"", name, value); } else if (value is IDictionary&lt;string, object&gt;) { sb.AppendFormat("\"{0}\":", name); new DynamicJsonObject((IDictionary&lt;string, object&gt;)value).ToString(sb); } else if (value is ArrayList) { sb.Append("\""); sb.Append(name); sb.Append("\":["); var firstInArray = true; foreach (var arrayValue in (ArrayList)value) { if (!firstInArray) sb.Append(","); firstInArray = false; if (arrayValue is IDictionary&lt;string, object&gt;) new DynamicJsonObject((IDictionary&lt;string, object&gt;)arrayValue).ToString(sb); else if (arrayValue is string) sb.AppendFormat("\"{0}\"", arrayValue); else sb.AppendFormat("{0}", arrayValue); } sb.Append("]"); } else { sb.AppendFormat("\"{0}\":{1}", name, value); } } sb.Append("}"); } public override bool TryGetMember(GetMemberBinder binder, out object result) { if (!_dictionary.TryGetValue(binder.Name, out result)) { // return null to avoid exception. caller can check for null this way... result = null; return true; } var dictionary = result as IDictionary&lt;string, object&gt;; if (dictionary != null) { result = new DynamicJsonObject(dictionary); return true; } var arrayList = result as ArrayList; if (arrayList != null &amp;&amp; arrayList.Count &gt; 0) { if (arrayList[0] is IDictionary&lt;string, object&gt;) result = new List&lt;object&gt;(arrayList.Cast&lt;IDictionary&lt;string, object&gt;&gt;().Select(x =&gt; new DynamicJsonObject(x))); else result = new List&lt;object&gt;(arrayList.Cast&lt;object&gt;()); } return true; } } public static class JsonMaker { public static Dictionary&lt;string, object&gt; ParseJSON(string json) { int end; return ParseJSON(json, 0, out end); } private static Dictionary&lt;string, object&gt; ParseJSON(string json, int start, out int end) { Dictionary&lt;string, object&gt; dict = new Dictionary&lt;string, object&gt;(); bool escbegin = false; bool escend = false; bool inquotes = false; string key = null; int cend; StringBuilder sb = new StringBuilder(); Dictionary&lt;string, object&gt; child = null; List&lt;object&gt; arraylist = null; Regex regex = new Regex(@"\\u([0-9a-z]{4})", RegexOptions.IgnoreCase); int autoKey = 0; bool inSingleQuotes = false; bool inDoubleQuotes = false; for (int i = start; i &lt; json.Length; i++) { char c = json[i]; if (c == '\\') escbegin = !escbegin; if (!escbegin) { if (c == '"' &amp;&amp; !inSingleQuotes) { inDoubleQuotes = !inDoubleQuotes; inquotes = !inquotes; if (!inquotes &amp;&amp; arraylist != null) { arraylist.Add(DecodeString(regex, sb.ToString())); sb.Length = 0; } continue; } else if (c == '\'' &amp;&amp; !inDoubleQuotes) { inSingleQuotes = !inSingleQuotes; inquotes = !inquotes; if (!inquotes &amp;&amp; arraylist != null) { arraylist.Add(DecodeString(regex, sb.ToString())); sb.Length = 0; } continue; } if (!inquotes) { switch (c) { case '{': if (i != start) { child = ParseJSON(json, i, out cend); if (arraylist != null) arraylist.Add(child); else { dict.Add(key.Trim(), child); key = null; } i = cend; } continue; case '}': end = i; if (key != null) { if (arraylist != null) dict.Add(key.Trim(), arraylist); else dict.Add(key.Trim(), DecodeString(regex, sb.ToString().Trim())); } return dict; case '[': arraylist = new List&lt;object&gt;(); continue; case ']': if (key == null) { key = "array" + autoKey.ToString(); autoKey++; } if (arraylist != null &amp;&amp; sb.Length &gt; 0) { arraylist.Add(sb.ToString()); sb.Length = 0; } dict.Add(key.Trim(), arraylist); arraylist = null; key = null; continue; case ',': if (arraylist == null &amp;&amp; key != null) { dict.Add(key.Trim(), DecodeString(regex, sb.ToString().Trim())); key = null; sb.Length = 0; } if (arraylist != null &amp;&amp; sb.Length &gt; 0) { arraylist.Add(sb.ToString()); sb.Length = 0; } continue; case ':': key = DecodeString(regex, sb.ToString()); sb.Length = 0; continue; } } } sb.Append(c); if (escend) escbegin = false; if (escbegin) escend = true; else escend = false; } end = json.Length - 1; return dict; //theoretically shouldn't ever get here } private static string DecodeString(Regex regex, string str) { return Regex.Unescape(regex.Replace(str, match =&gt; char.ConvertFromUtf32(Int32.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber)))); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload