Example #1
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
                       ));
        }
Example #2
0
        private static JsonValue Serialize(
            object subject,
            Type typeScope,
            SerializationContext context
            )
        {
            Type type = subject.GetType();

            // .NET primitives
            if (type.IsPrimitive)
            {
                return(DotNetPrimitivesSerializer.ToJson(subject, type));
            }

            // string
            if (type == typeof(string))
            {
                return((string)subject);
            }

            // enums
            if (type.IsEnum)
            {
                return(EnumSerializer.ToJson(subject));
            }

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

                return(ArraySerializer.ToJson(subject, typeScope, context));
            }

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

            // exact type serializers
            if (exactTypeSerializers.TryGetValue(searchType, out ITypeSerializer serializer))
            {
                return(serializer.ToJson(subject, typeScope, context));
            }

            // assignable type serializers
            foreach (var pair in assignableTypeSerializers)
            {
                if (pair.Key.IsAssignableFrom(searchType))
                {
                    return(pair.Value.ToJson(subject, typeScope, context));
                }
            }

            // unisave serializable
            if (typeof(IUnisaveSerializable).IsAssignableFrom(type))
            {
                return(UnisaveSerializableTypeSerializer.ToJson(
                           subject, typeScope, context
                           ));
            }

            // serializable
            if (typeof(ISerializable).IsAssignableFrom(type))
            {
                return(SerializableTypeSerializer.ToJson(
                           subject, typeScope, context
                           ));
            }

            // validate type scope
            if (!typeScope.IsAssignableFrom(type))
            {
                throw new ArgumentException(
                          $"Given subject is of type {type} that is not assignable " +
                          $"to the given type scope {typeScope}"
                          );
            }

            // other
            return(DefaultSerializer.ToJson(subject, typeScope, context));
        }