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