static void ProcessMap(object obj, SafeDictionary <string, TypePropertyInfo> props, Dictionary <string, object> dic) { foreach (var kv in dic) { var p = props[kv.Key]; var o = p.getter(obj); var t = Type.GetType((string)kv.Value); if (t == typeof(Guid)) { p.setter(obj, CreateGuid((string)o), null); } } }
/// <summary> /// Read the properties and public fields of a type. /// In special cases, this will also read private fields /// </summary> SafeDictionary <string, TypePropertyInfo> GetProperties(Type type, string typename) { bool usePrivateFields = typename.StartsWith("Tuple`") || IsAnonymousType(type); SafeDictionary <string, TypePropertyInfo> sd; if (propertyCache.TryGetValue(typename, out sd)) { return(sd); } sd = new SafeDictionary <string, TypePropertyInfo>(); var pr = new List <PropertyInfo>(); var fi = new List <FieldInfo>(); fi.AddRange(type.GetFields(BindingFlags.Public | BindingFlags.Instance)); if (usePrivateFields) { fi.AddRange(type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)); } foreach (var iface in type.GetInterfaces()) { fi.AddRange(iface.GetFields(BindingFlags.Public | BindingFlags.Instance)); } foreach (var f in fi) { var d = CreateMyProp(f.FieldType); d.setter = CreateSetField(type, f); d.getter = CreateGetField(type, f); sd.Add(f.Name, d); if (usePrivateFields) { sd.Add(AnonFieldFilter(f.Name.Replace("m_", "")), d); } } pr.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Instance)); foreach (var prop in type.GetInterfaces() .SelectMany(iface => iface.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(prop => pr.All(p => p.Name != prop.Name)))) { pr.Add(prop); } foreach (var p in pr) { var d = CreateMyProp(p.PropertyType); d.CanWrite = p.CanWrite; d.setter = CreateSetMethod(p); if (d.setter == null) { continue; } d.getter = CreateGetMethod(p); sd.Add(p.Name, d); } if (type.GetGenericArguments().Length < 1) { propertyCache.Add(typename, sd); } return(sd); }
/// <summary> /// Map json value dictionary to the properties and fields of a target object instance /// </summary> void MapJsonValueToObject(string objectKey, object targetObject, IDictionary <string, object> jsonValues, IDictionary <string, object> globaltypes, SafeDictionary <string, TypePropertyInfo> props) { var name = objectKey; if (jsonParameters.IgnoreCaseOnDeserialize) { name = name.ToLower(); } if (name == "$map") { ProcessMap(targetObject, props, (Dictionary <string, object>)jsonValues[name]); return; } TypePropertyInfo pi; if (props.TryGetValue(name, out pi) == false) { if (targetObject is IDictionary) { var ok = props.TryGetValue("Item", out pi); if (!ok) { return; } } else { return; } } if (!pi.filled) { return; } var v = jsonValues[name]; if (v == null) { return; } object oset; if (pi.isInt) { oset = (int)CreateLong(v); } else if (pi.isLong) { oset = CreateLong(v); } else if (pi.isString) { oset = v; } else if (pi.isBool) { oset = (bool)v; } else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false) { oset = CreateGenericList((ArrayList)v, pi.pt, pi.bt, globaltypes); } else if (pi.isByteArray) { oset = Convert.FromBase64String((string)v); } else if (pi.isArray && pi.isValueType == false) { oset = CreateArray((ArrayList)v, pi.bt, globaltypes); } else if (pi.isGuid) { oset = CreateGuid((string)v); } else if (pi.isDataSet) { oset = CreateDataset((Dictionary <string, object>)v, globaltypes); } else if (pi.isDataTable) { oset = CreateDataTable((Dictionary <string, object>)v, globaltypes); } else if (pi.isStringDictionary) { oset = CreateStringKeyDictionary((Dictionary <string, object>)v, pi.pt, pi.GenericTypes, globaltypes); } else if (pi.isDictionary || pi.isHashtable) { oset = CreateDictionary((ArrayList)v, pi.pt, pi.GenericTypes, globaltypes); } else if (pi.isEnum) { oset = CreateEnum(pi.pt, (string)v); } else if (pi.isDateTime) { oset = CreateDateTime((string)v); } else if (pi.isClass && v is Dictionary <string, object> objects) { oset = ParseDictionary(objects, globaltypes, pi.pt, null); } else if (pi.isValueType) { oset = ChangeType(v, pi.changeType); } else if (v is ArrayList list) { oset = CreateArray(list, typeof(object), globaltypes); } else { oset = v; } if (pi.CanWrite) { WriteValueToTypeInstance(name, targetObject, pi, oset); } }