Unable to serialize multi-dimensional array to JSON in dotnet core 3.1

Viewed 523

When I try to serialize a multi-dimensional array using the new built-in JSON serializer in dotnet core 3.1, I get an error:

int[,] foo = new int[5, 5];
var json = System.Text.Json.JsonSerializer.Serialize(foo);

System.NotSupportedException: 'The collection type 'System.Int32[,]' is not supported.'

Is there a way to use a custom JSON converter for multi-dimensional arrays?

2 Answers

Like this:

    int[][] foo = new int[][] { new []{1}, new [] {3, 4} };
    var json = System.Text.Json.JsonSerializer.Serialize(foo);
    Console.WriteLine(json); // [[1],[3,4]]

I have had implemented a partial solution for this issue.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;


public class MatrixConverter<T> : JsonConverter<T[,]>
{
    public override T[,] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {

        if (reader.TokenType != JsonTokenType.StartArray)
        {
            throw new JsonException();
        }

        reader.Read();

        if (reader.TokenType != JsonTokenType.StartArray)
        {
            throw new JsonException();
        }

        reader.Read();

        var elements = new List<List<T>>();

        var innerElements = new List<T>();

        int? qttOfElementsInFirstLine = null;

        while (reader.TokenType != JsonTokenType.EndArray)
        {
            while (reader.TokenType != JsonTokenType.EndArray)
            {
                innerElements.Add(JsonSerializer.Deserialize<T>(ref reader, options));
                reader.Read();
            }

            if (!qttOfElementsInFirstLine.HasValue)
            {
                qttOfElementsInFirstLine = innerElements.Count;
            }

            if (innerElements.Count != qttOfElementsInFirstLine)
            {
                throw new JsonException("the matrix must have teh same qauantity of elements in each line");
            }

            elements.Add(innerElements);

            reader.Read();
            if (reader.TokenType != JsonTokenType.StartArray && reader.TokenType != JsonTokenType.EndArray)
            {
                    throw new JsonException();
            }
            innerElements = new List<T>();
            reader.Read();
        }

        var ret = new T[elements.Count, qttOfElementsInFirstLine.Value];

        for (int i = 0; i < elements.Count; i++)
        {
            for (int j = 0; j < elements[i].Count; j++)
            {
                ret[i, j] = elements[i][j];
            }
        }

        return ret;
    }

    public override void Write(Utf8JsonWriter writer, T[,] value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}


The usage of the converter

    var serializeOptions = new JsonSerializerOptions
    {
        WriteIndented = true,
        Converters =
        {
            new MatrixConverter<double>()
        }
    };
    
    var s = "[[1,2,3],[1,2,3]]";
    var v = JsonSerializer.Deserialize<double[,]>(s, serializeOptions);
Related