Example #1
0
        public JsonValue ToJson(
            object subject,
            Type typeScope,
            SerializationContext context
            )
        {
            if (!(subject is Exception exception))
            {
                throw new ArgumentException(
                          "Provided instance is not an exception."
                          );
            }

            try
            {
                // every exception should be ISerializable
                return(SerializableTypeSerializer.ToJson(
                           subject,
                           typeScope,
                           context
                           ));
            }
            catch
            {
                // it doesn't want to be serialized,
                // so serialize at lest what can be pulled out manually
                // (we want to get at least some information to the client)
                return(new JsonObject()
                       .Add("ClassName", exception.GetType().FullName)
                       .Add("HResult", exception.HResult)
                       .Add("Message", exception.Message)
                       .Add("StackTraceString", exception.StackTrace));
            }
        }
Example #2
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));
            }
        }
Example #3
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 #4
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));
        }