private InstantiationData _InstantiateWithConstructor( JSONNode node, Type targetType, NodeOptions options, Deserializer deserializer) { if (node.IsNull || node.Tag == JSONNodeType.None) { return(InstantiationData.Null); } JSONObjectAttribute objectAttribute = Util.GetAttribute <JSONObjectAttribute> (targetType); bool useTupleFormat = objectAttribute != null ? objectAttribute.options.ShouldUseTupleFormat() : false; if (useTupleFormat && !node.IsArray) { throw new InstantiationException("Expected JSON array, found " + node.Tag); } else if (!useTupleFormat && !node.IsObject) { throw new InstantiationException("Expected JSON object, found " + node.Tag); } ConstructorInfo[] constructors = targetType.GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (ConstructorInfo constructorInfo in constructors) { var constructorAttribute = Util.GetAttribute <JSONConstructorAttribute> (constructorInfo); if (constructorAttribute != null) { return(_InstantiateWithConstructor(node, constructorInfo, deserializer, useTupleFormat)); } } try { InstantiationData instantiationData = new InstantiationData(); instantiationData.instantiatedObject = Activator.CreateInstance(targetType); instantiationData.needsDeserialization = node.Count != 0; return(instantiationData); } catch (Exception) { return(_HandleError(options, "Type " + targetType + " does not have a suitable constructor.")); } }
private string _SerializeCustom(object obj, NodeOptions options) { ISerializationListener listener = obj as ISerializationListener; if (listener != null) { listener.OnSerializationWillBegin(this); } try { IEnumerable <string> enumerable = new string[] { }; MemberInfo extrasMember = null; JSONExtrasAttribute extrasAttribute = null; // Find member info and attribute for extras while going over the // fields and properties. Func <MemberInfo, bool> isNotExtras = m => { if (extrasMember == null && Util.IsJSONExtrasMember(m, out extrasAttribute)) { extrasMember = m; return(false); } else { return(true); } }; Type type = obj.GetType(); JSONObjectAttribute objectAttribute = Util.GetAttribute <JSONObjectAttribute> (type); var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; bool useTupleFormat = false; if (objectAttribute != null) { if (!objectAttribute.options.ShouldIgnoreStatic()) { flags |= BindingFlags.Static; } if (objectAttribute.options.ShouldUseTupleFormat()) { useTupleFormat = true; } } enumerable = enumerable.Concat( from f in type.GetFields(flags) where isNotExtras(f) && _IsValidFieldInfo(f) select _SerializeCustomField(obj, f, useTupleFormat)); if (objectAttribute == null || !objectAttribute.options.ShouldIgnoreProperties()) { enumerable = enumerable.Concat( from p in type.GetProperties(flags) where isNotExtras(p) && _IsValidPropertyInfo(p) select _SerializeCustomProperty(obj, p, useTupleFormat)); } // Serialize all properties and fields. var result = _Join(enumerable, o => o as string); // Serialize the extras if there are any. if (!useTupleFormat && extrasMember != null) { var extras = Util.GetMemberValue(extrasMember, obj) as IEnumerable; if (extras != null) { result += (result == "" ? "" : ",") + _SerializeEnumarable(extras, extrasAttribute.options); } } if (listener != null) { listener.OnSerializationSucceeded(this); } if (useTupleFormat) { return("[" + result + "]"); } else { return("{" + result + "}"); } } catch (Exception exception) { if (listener != null) { listener.OnSerializationFailed(this); } throw exception; } }