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