I have a class which uses a System.Memory Property, let’s call it PROP1 and CLASS1
When this class is serialized into a JSON file it’s saved in a pretty common way :
(…) "PROP1":[7200.0,7200.0,7200.0] (…)
When I try to deserialize via JsonConvert.DeserializeObject<CLASS1>File.ReadAllText(fileName));
I get the following exception :
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
‘System.Memory`1[System.Double]’ because the type requires a JSON
object (e.g. {"name":"value"}) to deserialize correctly. To fix this
error either change the JSON to a JSON object (e.g. {"name":"value"})
or change the deserialized type to an array or a type that implements
a collection interface (e.g. ICollection, IList) like List that can
be deserialized from a JSON array. JsonArrayAttribute can also be
added to the type to force it to deserialize from a JSON array.
I guess it cannot serialize it because Memory is working more like a pointer, so you should create an object first which the Memory refers to. But I could not find a fix to this (besides rewriting the class to another type)…and I couldn’t find any threads with a similiar problem. Any ideas how to deserialize it??
Thank you very much for reading!
2
Answers
You can use a custom
JsonConverter
.Then you can apply it
Since Json.NET doesn’t seem to have built-in support for serializing and deserializing
Memory<T>
andReadOnlyMemory<T>
, you could create generic converters for them that will serialize and deserialize "snapshots" of the contents ofMemory<T>
andReadOnlyMemory<T>
slices as follows:Then you would serialize and deserialize your model using the following settings:
And/or apply to your model as follows:
Warnings and notes:
Warning: references of array slices are not preserved. If your
Memory<double>
is a slice of some array, and that array is also being serialized elsewhere in the model, then when deserialized theMemory<double>
will not refer to the deserialized array by reference, it will refer to its own copy of the array.If you need to preserve the references of array slices, a different (and much more complicated) converter would be required.
Since byte arrays are serialized as Base64 strings by Json.NET (and System.Text.Json), I did the same for
Memory<byte>
andReadOnlyMemory<byte>
. But if theMemory<byte>
had been previously serialized as a JSON array, it will be read properly.Since
ReadOnlyMemory<char>
can sometimes wrap a string, I serialized it as such, but did not do the same forMemory<char>
which can only wrap a char array.If you don’t want that, pass
serializeAsString : false
insideReadOnlyMemoryConverter<T>.Read()
.Absent the converters, I was unable to generate a reasonable serialization for
Memory<T>
out of the box with Json.NET 13.0.3. Instead of a JSON array, I gotMaybe you already have some converter installed that handles serialization but not deserialization?
Demo fiddle here.