<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />

DataTableConverter

Converts a DataTable to and from JSON.
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Globalization; namespace Newtonsoft.Json.Converters { public class DataTableConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) writer.WriteNull(); else { DataTable obj = (DataTable)value; DefaultContractResolver defaultContractResolver = serializer.ContractResolver as DefaultContractResolver; writer.WriteStartArray(); foreach (DataRow row in obj.Rows) { writer.WriteStartObject(); foreach (DataColumn column in row.Table.Columns) { object obj2 = row[column]; if (serializer.NullValueHandling != NullValueHandling.Ignore || (obj2 != null && obj2 != DBNull.Value)) { writer.WritePropertyName((defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName); serializer.Serialize(writer, obj2); } } writer.WriteEndObject(); } writer.WriteEndArray(); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) return null; DataTable dataTable; if ((dataTable = (existingValue as DataTable)) == null) dataTable = ((objectType == typeof(DataTable)) ? new DataTable() : ((DataTable)Activator.CreateInstance(objectType))); if (reader.TokenType == JsonToken.PropertyName) { dataTable.TableName = (string)reader.Value; reader.ReadAndAssert(); if (reader.TokenType == JsonToken.Null) return dataTable; } if (reader.TokenType != JsonToken.StartArray) throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); reader.ReadAndAssert(); while (reader.TokenType != JsonToken.EndArray) { CreateRow(reader, dataTable, serializer); reader.ReadAndAssert(); } return dataTable; } private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer serializer) { DataRow dataRow = dt.NewRow(); reader.ReadAndAssert(); while (reader.TokenType == JsonToken.PropertyName) { string text = (string)reader.Value; reader.ReadAndAssert(); DataColumn dataColumn = dt.Columns[text]; if (dataColumn == null) { Type columnDataType = GetColumnDataType(reader); dataColumn = new DataColumn(text, columnDataType); dt.Columns.Add(dataColumn); } if (dataColumn.DataType == typeof(DataTable)) { if (reader.TokenType == JsonToken.StartArray) reader.ReadAndAssert(); DataTable dataTable = new DataTable(); while (reader.TokenType != JsonToken.EndArray) { CreateRow(reader, dataTable, serializer); reader.ReadAndAssert(); } dataRow[text] = dataTable; } else if (!dataColumn.DataType.IsArray || !(dataColumn.DataType != typeof(byte[]))) { object obj2 = dataRow[text] = ((reader.Value != null) ? (serializer.Deserialize(reader, dataColumn.DataType) ?? DBNull.Value) : DBNull.Value); } else { if (reader.TokenType == JsonToken.StartArray) reader.ReadAndAssert(); List<object> list = new List<object>(); while (reader.TokenType != JsonToken.EndArray) { list.Add(reader.Value); reader.ReadAndAssert(); } Array array = Array.CreateInstance(dataColumn.DataType.GetElementType(), list.Count); ((ICollection)list).CopyTo(array, 0); dataRow[text] = array; } reader.ReadAndAssert(); } dataRow.EndEdit(); dt.Rows.Add(dataRow); } private static Type GetColumnDataType(JsonReader reader) { JsonToken tokenType = reader.TokenType; switch (tokenType) { case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Date: case JsonToken.Bytes: return reader.ValueType; case JsonToken.Null: case JsonToken.Undefined: case JsonToken.EndArray: return typeof(string); case JsonToken.StartArray: reader.ReadAndAssert(); if (reader.TokenType == JsonToken.StartObject) return typeof(DataTable); return GetColumnDataType(reader).MakeArrayType(); default: throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType)); } } public override bool CanConvert(Type valueType) { return typeof(DataTable).IsAssignableFrom(valueType); } } }