Serialize DataSet with current version of System.Text.Json.JsonSerializer

前端 未结 2 1624
忘了有多久
忘了有多久 2021-01-23 15:41

Do you have any advice on how we can serialize DataSet,DataTable with System.Text.Json.JsonSerializer ?
Currently it throws this exceptio

相关标签:
2条回答
  • 2021-01-23 16:02

    Reference loop handling is not currently supported using System.Text.Json. Workarounds:

    .Net Core 3.0 possible object cycle was detected which is not supported

    https://www.thecodebuzz.com/jsonexception-possible-object-cycle-detected-object-depth/

    You could add custom converters on the offending property to deal with an object referring to itself or just add a JsonIgnore attribute to the offending property.

    0 讨论(0)
  • 2021-01-23 16:17

    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

    0 讨论(0)
提交回复
热议问题