/// <summary> /// Make a JsonObject from the provided .NET business object using the JsonMaker for type t. /// </summary> public JsonObject MakeJson(object obj, Type t) { if (t != null) { return(GetJsonMaker(t)(obj)); } else { return(JsonObject.Null); } }
private JsonMaker MakeJsonMaker(Type objectType) { // Specific custom deserialization JsonMaker customMaker = _TranslatorExtensions?.MakeJsonMaker(objectType); if (customMaker != null) { return(customMaker); } // String if (objectType == typeof(string)) { return(obj => { if (obj == null) { return JsonObject.Null; } else { return new JsonObject(obj as string); } }); } // Nullable types if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Nullable <>)) { JsonMaker subObjectMaker = MakeJsonMaker(objectType.GetGenericArguments()[0]); return(obj => { if (obj == null) { return JsonObject.Null; } else { return subObjectMaker(obj); } }); } // Enums if (objectType.IsEnum) { return(obj => new JsonObject(obj.ToString())); } // Simple types foreach (var kvp in SIMPLE_TYPES) { if (objectType == kvp.Key) { ConstructorInfo jtc = typeof(JsonObject).GetConstructor(new Type[] { kvp.Key }); return(obj => (JsonObject)jtc.Invoke(new object[] { obj })); } } // Parseable from string Func <string, object> parser = JsonReflection.GetParser(objectType); if (parser != null) { Func <object, string> toString = JsonReflection.GetToString(objectType); return(obj => new JsonObject(toString(obj))); } // Explicit Dictionary JsonReflection.DictionaryInfo dinfo = JsonReflection.IsDictionary(objectType); if (dinfo != null) { if (JsonReflection.GetParser(dinfo.KeyType) == null) { throw new InvalidOperationException("Cannot create JsonMaker for type " + objectType.FullName + " because key type " + dinfo.KeyType.FullName + " cannot be parsed from a string"); } JsonMaker valueMaker = GetJsonMaker(dinfo.ValueType); Type kvpType = typeof(KeyValuePair <,>).MakeGenericType(new Type[] { dinfo.KeyType, dinfo.ValueType }); PropertyInfo keyProperty = kvpType.GetProperty("Key"); PropertyInfo valueProperty = kvpType.GetProperty("Value"); return(obj => { if (obj == null) { return JsonObject.Null; } var result = JsonObject.EmptyDictionary; foreach (var kvp in obj as IEnumerable) { result[keyProperty.GetValue(kvp).ToString()] = valueMaker(valueProperty.GetValue(kvp)); } return result; }); } // Array Type contentType = JsonReflection.GetEnumerableType(objectType); if (contentType != null) { return(obj => { if (obj == null) { return JsonObject.Null; } JsonMaker itemMaker = GetJsonMaker(contentType); var items = new List <JsonObject>(); foreach (object item in (IEnumerable)obj) { items.Add(itemMaker(item)); } return new JsonObject(items); }); } // Object-as-Dictionary (choice of last resort) object defaultObj = JsonReflection.GetDefaultMaker(objectType)(); var getters = new Dictionary <string, MemberGetter>(); var types = new Dictionary <string, Type>(); var equalities = new Dictionary <string, MethodInfo>(); FieldInfo[] fields = objectType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo fi in fields) { if (fi.GetCustomAttribute <JsonIgnoreAttribute>() != null) { continue; } string name = AdjustedFieldName(fi.Name); getters[name] = obj => fi.GetValue(obj); types[name] = fi.FieldType; equalities[name] = fi.FieldType.GetMethod("Equals", new Type[] { typeof(object) }); } return(obj => { var jfields = new Dictionary <string, JsonObject>(); foreach (var kvp in getters) { object objVal = kvp.Value(obj); object defVal = kvp.Value(defaultObj); MethodInfo equality = equalities[kvp.Key]; bool equal = defVal == null ? objVal == null : (bool)equality.Invoke(defVal, new object[] { objVal }); if (!equal) { jfields[kvp.Key] = GetJsonMaker(types[kvp.Key])(objVal); } } return new JsonObject(jfields); }); }
/// <summary> /// Make a JsonObject from the provided .NET business object using the JsonMaker for type T. /// </summary> public JsonObject MakeJson <T>(T obj) { return(GetJsonMaker(typeof(T))(obj)); }