Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

asp.net core - Serialize DataSet with current version of System.Text.Json.JsonSerializer

Do you have any advice on how we can serialize DataSet,DataTable with System.Text.Json.JsonSerializer ?
Currently it throws this exception : '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 64.'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is currently no built-in support for types like DataSet and DataTable in System.Text.Json (as of.NET Core 3.1). To be able to serialize such types, you will need to implement your own JsonConverter<T> for the types you need and register it within the JsonSerializerOptions. Writing one for serialization for the particular types you asked for should be fairly easy.

Here's an example that should work for serialization (left out the deserialization component):

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

This document might provide more guidance: https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...