internal object ParseDictionary(Dictionary <string, object> target, Dictionary <string, object> globalTypes, Type type, object input) { if (type == typeof(NameValueCollection)) { return(Helper.CreateNV(target)); } if (type == typeof(StringDictionary)) { return(Helper.CreateSD(target)); } if (target.TryGetValue("$i", out object tn)) { ReverseCircularObject.TryGetValue((int)(long)tn, out object v); return(v); } if (target.TryGetValue("$types", out tn)) { UseGlobals = true; if (globalTypes == null) { globalTypes = new Dictionary <string, object>(); } foreach (KeyValuePair <string, object> kv in (Dictionary <string, object>)tn) { globalTypes.Add((string)kv.Value, kv.Key); } } if (globalTypes != null) { UseGlobals = true; } bool found = target.TryGetValue("$type", out tn); if (found == false && type == typeof(object)) { return(target); // CreateDataset(d, globaltypes); } if (found) { if (UseGlobals) { if (globalTypes != null && globalTypes.TryGetValue((string)tn, out object tname)) { tn = tname; } } type = Reflection.Instance.GetTypeFromCache((string)tn); } if (type == null) { throw new Exception("Cannot determine type"); } string typename = type.FullName; object o = input; if (o == null) { o = Configuration.ParametricConstructorOverride ? System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type) : Reflection.Instance.FastCreateInstance(type); } if (CircularObject.TryGetValue(o, out int circount) == false) { circount = CircularObject.Count + 1; CircularObject.Add(o, circount); ReverseCircularObject.Add(circount, o); } Dictionary <string, PropInfo> props = Reflection.Instance.Getproperties(type, typename, Configuration.ShowReadOnlyProperties); foreach (KeyValuePair <string, object> kv in target) { string n = kv.Key; object v = kv.Value; string name = n;//.ToLower(); if (name == "$map") { ProcessMap(o, props, (Dictionary <string, object>)target[name]); continue; } if (props.TryGetValue(name, out PropInfo pi) == false) { if (props.TryGetValue(name.ToLowerInvariant(), out pi) == false) { continue; } } if (pi.CanWrite) { if (v != null) { object oset = null; switch (pi.Type) { case PropInfoType.Int: oset = (int)Helper.AutoConv(v); break; case PropInfoType.Long: oset = Helper.AutoConv(v); break; case PropInfoType.String: oset = v.ToString(); break; case PropInfoType.Bool: oset = Helper.BoolConv(v); break; case PropInfoType.DateTime: oset = Helper.CreateDateTime((string)v, Configuration.UseUTCDateTime); break; case PropInfoType.Enum: oset = Helper.CreateEnum(pi.pt, v); break; case PropInfoType.Guid: oset = Helper.CreateGuid((string)v); break; case PropInfoType.Array: if (!pi.IsValueType) { oset = CreateArray((List <object>)v, pi.pt, pi.bt, globalTypes); } // what about 'else'? break; case PropInfoType.ByteArray: oset = Convert.FromBase64String((string)v); break; case PropInfoType.DataSet: oset = CreateDataset((Dictionary <string, object>)v, globalTypes); break; case PropInfoType.DataTable: oset = CreateDataTable((Dictionary <string, object>)v, globalTypes); break; case PropInfoType.Hashtable: // same case as Dictionary case PropInfoType.Dictionary: oset = CreateDictionary((List <object>)v, pi.pt, pi.GenericTypes, globalTypes); break; case PropInfoType.StringKeyDictionary: oset = CreateStringKeyDictionary((Dictionary <string, object>)v, pi.pt, pi.GenericTypes, globalTypes); break; case PropInfoType.NameValue: oset = Helper.CreateNV((Dictionary <string, object>)v); break; case PropInfoType.StringDictionary: oset = Helper.CreateSD((Dictionary <string, object>)v); break; case PropInfoType.Custom: oset = Reflection.Instance.CreateCustom((string)v, pi.pt); break; default: { oset = pi.IsGenericType && pi.IsValueType == false && v is List <object> ?CreateGenericList((List <object>) v, pi.pt, pi.bt, globalTypes) : (pi.IsClass || pi.IsStruct || pi.IsInterface) && v is Dictionary <string, object> ?ParseDictionary((Dictionary <string, object>) v, globalTypes, pi.pt, null) : v is List <object> ?CreateArray((List <object>) v, pi.pt, typeof(object), globalTypes) : pi.IsValueType ? ChangeType(v, pi.changeType) : v; } break; } o = pi.setter(o, oset); } } } return(o); }