Esempio n. 1
0
        public object FromJson(
            JsonValue json,
            Type deserializationType,
            DeserializationContext context
            )
        {
            // NOTE: deserialization shouldn't fail no matter what the JSON is.
            // Instead a SerializedException instance should be returned.
            // The only exception is improper usage of this method.

            if (!typeof(Exception).IsAssignableFrom(deserializationType))
            {
                throw new ArgumentException(
                          "Provided type is not an exception."
                          );
            }

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

            try
            {
                if (json.IsString)
                {
                    return(LegacyFromJson(json));
                }
            }
            catch (Exception e)
            {
                // RETURN, not throw!
                return(new SerializedException(json, e));
            }

            JsonObject obj = json.AsJsonObject;

            if (obj == null)
            {
                return(null);
            }

            try
            {
                // deserialize the thing
                Type actualType = FindExceptionType(obj["ClassName"].AsString);
                SerializationInfo defaultInfo = GetDefaultSerializationInfo(actualType);
                ExtendJsonWithDefaultSerializationInfo(obj, defaultInfo);
                var e = SerializableTypeSerializer.FromJson(obj, actualType, context);
                PreserveStackTrace((Exception)e);
                return(e);
            }
            catch (Exception e)
            {
                // RETURN, not throw!
                return(new SerializedException(json, e));
            }
        }
Esempio n. 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
                       ));
        }