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)); } }
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 )); }