Сериализация DataSet с текущей версией System.Text. Json .JsonSerializer - PullRequest
1 голос
/ 17 января 2020

Есть ли у вас какие-либо советы о том, как мы можем сериализовать DataSet, DataTable с System.Text. Json .JsonSerializer ? В настоящее время он выдает это исключение: 'Обнаружен возможный цикл объекта, который не поддерживается. Это может быть связано с циклом или если глубина объекта превышает максимально допустимую глубину 64. '

1 Ответ

2 голосов
/ 17 января 2020

В настоящее время нет встроенной поддержки для таких типов, как DataSet и DataTable в System.Text.Json (по состоянию на NET Core 3.1). Чтобы иметь возможность сериализовать такие типы, вам нужно реализовать свой собственный JsonConverter<T> для нужных вам типов и зарегистрировать его в JsonSerializerOptions. Написание одного для сериализации для определенных типов, которые вы запрашивали, должно быть довольно простым.

Вот пример, который должен работать для сериализации (исключая компонент десериализации):

public class DataTableConverter : JsonConverter<DataTable>
{
    public override DataTable Read(ref Utf8JsonReader reader, Type typeToConvert,
        JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, DataTable value,
        JsonSerializerOptions options)
    {
        writer.WriteStartArray();

        foreach (DataRow row in value.Rows)
        {
            writer.WriteStartObject();
            foreach (DataColumn column in row.Table.Columns)
            {
                object columnValue = row[column];

                // If necessary:
                if (options.IgnoreNullValues)
                {
                    // Do null checks on the values here and skip writing.
                }

                writer.WritePropertyName(column.ColumnName);
                JsonSerializer.Serialize(writer, columnValue, options);
            }
            writer.WriteEndObject();
        }

        writer.WriteEndArray();
    }
}

public class DataSetConverter : JsonConverter<DataSet>
{
    public override DataSet Read(ref Utf8JsonReader reader, Type typeToConvert,
        JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, DataSet value,
        JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        foreach (DataTable table in value.Tables)
        {
            writer.WritePropertyName(table.TableName);
            JsonSerializer.Serialize(writer, table, options);
        }
        writer.WriteEndObject();
    }
}

private static void DataSet_Serialization_WithSystemTextJson()
{
    var options = new JsonSerializerOptions()
    {
        Converters = { new DataTableConverter(), new DataSetConverter() }
    };

    (DataTable table, DataSet dataSet) = GetDataSetAndTable();

    string jsonDataTable = JsonSerializer.Serialize(table, options);
    // [{"id":0,"item":"item 0"},{"id":1,"item":"item 1"}]
    Console.WriteLine(jsonDataTable);

    string jsonDataSet = JsonSerializer.Serialize(dataSet, options);
    // {"Table1":[{"id":0,"item":"item 0"},{"id":1,"item":"item 1"}]}
    Console.WriteLine(jsonDataSet);

    // Local function to create a sample DataTable and DataSet
    (DataTable, DataSet) GetDataSetAndTable()
    {
        dataSet = new DataSet("dataSet");

        table = new DataTable();
        DataColumn idColumn = new DataColumn("id", typeof(int))
        {
            AutoIncrement = true
        };

        DataColumn itemColumn = new DataColumn("item");

        table.Columns.Add(idColumn);
        table.Columns.Add(itemColumn);

        dataSet.Tables.Add(table);

        for (int i = 0; i < 2; i++)
        {
            DataRow newRow = table.NewRow();
            newRow["item"] = "item " + i;
            table.Rows.Add(newRow);
        }

        dataSet.AcceptChanges();

        return (table, dataSet);
    }
}

Этот документ может предоставить дополнительные указания: https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to

...