Beispiel #1
0
        public object FromJson(
            JsonValue json,
            Type deserializationType,
            DeserializationContext context
            )
        {
            // legacy format
            if (json.IsJsonObject)
            {
                return(DefaultSerializer.FromJson(
                           json, deserializationType, context
                           ));
            }

            // NOPE! this rounds to milliseconds:
            //return TimeSpan.FromSeconds(json.AsNumber);

            return(new TimeSpan((long)(json.AsNumber * TimeSpan.TicksPerSecond)));
        }
Beispiel #2
0
        public static object FromJson(
            JsonValue json,
            Type typeScope,
            DeserializationContext context = default(DeserializationContext)
            )
        {
            // === Handle null ===

            if (json.IsNull)
            {
                return(null);
            }

            // === Parse and validate arguments ===

            if (typeScope == null)
            {
                throw new ArgumentNullException(nameof(typeScope));
            }

            // context cannot be null, no need to check

            // === Guard insecure deserialization ===

            if (!context.suppressInsecureDeserializationException)
            {
                if (typeScope == typeof(object))
                {
                    throw new InsecureDeserializationException(
                              "You cannot deserialize unknown data to an 'object' " +
                              "or 'dynamic' variable, as it poses a security risk. " +
                              "Read the security section of the serialization " +
                              "documentation to learn more."
                              );
                }
            }

            // === Determine deserialization type (the "$type" argument) ===

            Type deserializationType = GetDeserializationType(json, typeScope);

            // === Call static constructor of the deserialized type ===

            RuntimeHelpers.RunClassConstructor(deserializationType.TypeHandle);

            // === Deserialize ===

            // .NET primitives
            if (typeScope.IsPrimitive)
            {
                return(DotNetPrimitivesSerializer.FromJson(json, typeScope));
            }

            // string
            if (typeScope == typeof(string))
            {
                return(json.AsString);
            }

            // enums
            if (typeScope.IsEnum)
            {
                return(EnumSerializer.FromJson(json, typeScope));
            }

            // arrays
            if (typeScope.IsArray)
            {
                // binary data
                if (typeScope == typeof(byte[]))
                {
                    return(BinarySerializer.FromJson(json, typeScope, context));
                }

                return(ArraySerializer.FromJson(json, typeScope, context));
            }

            // by what type value to search through ITypeSerializers
            var searchType = typeScope.IsGenericType
                ? typeScope.GetGenericTypeDefinition()
                : typeScope;

            // exact type serializers
            if (exactTypeSerializers.TryGetValue(searchType, out ITypeSerializer serializer))
            {
                return(serializer.FromJson(json, deserializationType, context));
            }

            // assignable type serializers
            foreach (var pair in assignableTypeSerializers)
            {
                if (pair.Key.IsAssignableFrom(searchType))
                {
                    return(pair.Value.FromJson(json, deserializationType, context));
                }
            }

            // unisave serializable
            if (typeof(IUnisaveSerializable).IsAssignableFrom(deserializationType))
            {
                return(UnisaveSerializableTypeSerializer.FromJson(
                           json, deserializationType, context
                           ));
            }

            // serializable
            if (typeof(ISerializable).IsAssignableFrom(deserializationType))
            {
                return(SerializableTypeSerializer.FromJson(
                           json, deserializationType, context
                           ));
            }

            // other
            return(DefaultSerializer.FromJson(
                       json,
                       deserializationType,
                       context
                       ));
        }
        public object FromJson(
            JsonValue json,
            Type deserializationType,
            DeserializationContext context
            )
        {
            // legacy format
            if (json.IsJsonObject)
            {
                return(DefaultSerializer.FromJson(
                           json, deserializationType, context
                           ));
            }

            JsonArray jsonArray = json.AsJsonArray;

            if (jsonArray == null)
            {
                throw new UnisaveSerializationException(
                          "Given JSON cannot be deserialized as a Tuple."
                          );
            }

            if (jsonArray.Count == 0)
            {
                throw new UnisaveSerializationException(
                          "Empty JSON array cannot be deserialized as a Tuple."
                          );
            }

            Type[] typeArgs = deserializationType.GenericTypeArguments;

            ConstructorInfo ci = deserializationType.GetConstructor(typeArgs);

            if (ci == null)
            {
                throw new UnisaveSerializationException(
                          $"Cannot construct type {deserializationType}"
                          );
            }

            object[] items = new object[typeArgs.Length];

            for (int i = 0; i < items.Length; i++)
            {
                // handle long tuples (recursively)
                if (i == 7)
                {
                    if (!typeArgs[i].IsGenericType ||
                        !IsTupleType(typeArgs[i].GetGenericTypeDefinition()))
                    {
                        throw new UnisaveSerializationException(
                                  "Eighth tuple value has to be another tuple."
                                  );
                    }

                    items[7] = FromJson(jsonArray, typeArgs[7], context);
                    break;
                }

                items[i] = Serializer.FromJson(jsonArray[0], typeArgs[i], context);
                jsonArray.Remove(0);
            }


            return(ci.Invoke(items));
        }