-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Closed
Description
Scenario from https://github.com/dotnet/corefx/issues/41002#issuecomment-558058956 by @doogdeb
Serializing/deserializing a POCO containing a System.Type properties doesn't work today and fails with JsonException (A possible object cycle was detected which is not supported...). The workaround is to use a custom converter.
public static void SerializePocoWithType()
{
var cache = new CacheModel
{
DtoModelType = typeof(string),
CacheKey = "ABC"
};
// {"DtoModelType":"System.String, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","CacheKey":"ABC"}
Console.WriteLine(JsonConvert.SerializeObject(cache));
Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject<CacheModel>(JsonConvert.SerializeObject(cache))));
// Workaround for System.Type with S.T.Json using converters
var options = new JsonSerializerOptions();
options.Converters.Add(new CustomJsonConverterForType());
Console.WriteLine(JsonSerializer.Serialize(cache, options));
Console.WriteLine(JsonSerializer.Serialize(JsonSerializer.Deserialize<CacheModel>(JsonSerializer.Serialize(cache, options), options), options));
JsonSerializer.Serialize(cache);
/*
* System.Text.Json.Serialization.Tests.ReadValueTests.SerializePocoWithType [FAIL]
System.Text.Json.JsonException : A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 0.
Stack Trace:
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\ThrowHelper.Serialization.cs(33,0): at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.cs(45,0): at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(140,0): at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(112,0): at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(87,0): at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.String.cs(21,0): at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Serialization\ReadValueTests.cs(29,0): at System.Text.Json.Serialization.Tests.ReadValueTests.SerializePocoWithType()
*/
JsonSerializer.Serialize(cache, new JsonSerializerOptions { MaxDepth = 1_000 });
/*
* SerializePocoWithType [FAIL]
System.Text.Json.JsonException : The object or value could not be serialized. Path: $.DtoModelType.Assembly.DefinedTypes.GenericTypeParameters.Assembly.DefinedTypes.GenericTypeParameters.Assembly....DefinedTypes.GenericTypeParameters.Assembly.DefinedTypes.GenericTypeParameters.
---- System.InvalidOperationException : CurrentDepth (1000) is equal to or larger than the maximum allowed depth of 1000. Cannot write the next JSON object or array.
Stack Trace:
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\ThrowHelper.Serialization.cs(202,0): at System.Text.Json.ThrowHelper.ReThrowWithPath(WriteStack& writeStack, Exception ex)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.cs(70,0): at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(140,0): at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(112,0): at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.Helpers.cs(87,0): at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.String.cs(21,0): at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Serialization\ReadValueTests.cs(30,0): at System.Text.Json.Serialization.Tests.ReadValueTests.SerializePocoWithType()
----- Inner Stack Trace -----
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\ThrowHelper.cs(142,0): at System.Text.Json.ThrowHelper.ThrowInvalidOperationException(String message)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\ThrowHelper.cs(138,0): at System.Text.Json.ThrowHelper.ThrowInvalidOperationException(Int32 currentDepth)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Writer\Utf8JsonWriter.cs(606,0): at System.Text.Json.Utf8JsonWriter.WriteStartHelper(ReadOnlySpan`1 utf8PropertyName, Byte token)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Writer\Utf8JsonWriter.cs(583,0): at System.Text.Json.Utf8JsonWriter.WriteStartArray(JsonEncodedText propertyName)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\WriteStackFrame.cs(90,0): at System.Text.Json.WriteStackFrame.WriteObjectOrArrayStart(ClassType classType, JsonEncodedText propertyName, Utf8JsonWriter writer, Boolean writeNull)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\WriteStackFrame.cs(72,0): at System.Text.Json.WriteStackFrame.WriteObjectOrArrayStart(ClassType classType, Utf8JsonWriter writer, JsonSerializerOptions options, Boolean writeNull)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.HandleEnumerable.cs(47,0): at System.Text.Json.JsonSerializer.HandleEnumerable(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Write.cs(45,0): at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
Finished: System.Text.Json.Test
*/
}
// Sample workaround for System.Type with S.T.Json using converters
internal class CustomJsonConverterForType : JsonConverter<Type>
{
public override Type Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Caution: Deserialization of type instances like this is not recommended and should be avoided
// since it can lead to potential security issues.
// string assemblyQualifiedName = reader.GetString();
// return Type.GetType(assemblyQualifiedName);
throw new NotSupportedException();
}
public override void Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.AssemblyQualifiedName);
}
}cc @steveharter, @layomia, @jozkee
Reactions are currently unavailable