示例#1
0
        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."));
            }
        }
示例#2
0
        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;
            }
        }