public object FromJson( JsonValue json, Type deserializationType, DeserializationContext context ) { // legacy format if (json.IsJsonObject) { return(DefaultSerializer.FromJson( json, deserializationType, context )); } // NOPE! this rounds to milliseconds: //return TimeSpan.FromSeconds(json.AsNumber); return(new TimeSpan((long)(json.AsNumber * TimeSpan.TicksPerSecond))); }
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 )); }
public object FromJson( JsonValue json, Type deserializationType, DeserializationContext context ) { // legacy format if (json.IsJsonObject) { return(DefaultSerializer.FromJson( json, deserializationType, context )); } JsonArray jsonArray = json.AsJsonArray; if (jsonArray == null) { throw new UnisaveSerializationException( "Given JSON cannot be deserialized as a Tuple." ); } if (jsonArray.Count == 0) { throw new UnisaveSerializationException( "Empty JSON array cannot be deserialized as a Tuple." ); } Type[] typeArgs = deserializationType.GenericTypeArguments; ConstructorInfo ci = deserializationType.GetConstructor(typeArgs); if (ci == null) { throw new UnisaveSerializationException( $"Cannot construct type {deserializationType}" ); } object[] items = new object[typeArgs.Length]; for (int i = 0; i < items.Length; i++) { // handle long tuples (recursively) if (i == 7) { if (!typeArgs[i].IsGenericType || !IsTupleType(typeArgs[i].GetGenericTypeDefinition())) { throw new UnisaveSerializationException( "Eighth tuple value has to be another tuple." ); } items[7] = FromJson(jsonArray, typeArgs[7], context); break; } items[i] = Serializer.FromJson(jsonArray[0], typeArgs[i], context); jsonArray.Remove(0); } return(ci.Invoke(items)); }