Advertisement
Guest User

JsonDefaultTypeDataTableConverter<T>

a guest
Sep 23rd, 2015
527
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.04 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Globalization;
  3. using Newtonsoft.Json.Utilities;
  4. using System;
  5. using System.Data;
  6. using Newtonsoft.Json.Serialization;
  7. using Newtonsoft.Json;
  8.  
  9. namespace Tile
  10. {
  11.     /// <summary>
  12.     /// Converts a <see cref="DataTable"/> to and from JSON.
  13.     /// Adapted from https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
  14.     /// </summary>
  15.     public class JsonDefaultTypeDataTableConverter<T>  : JsonConverter
  16.     {
  17.         /// <summary>
  18.         /// Writes the JSON representation of the object.
  19.         /// </summary>
  20.         /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
  21.         /// <param name="value">The value.</param>
  22.         /// <param name="serializer">The calling serializer.</param>
  23.         public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  24.         {
  25.             DataTable table = (DataTable)value;
  26.             DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
  27.  
  28.             writer.WriteStartArray();
  29.  
  30.             foreach (DataRow row in table.Rows)
  31.             {
  32.                 writer.WriteStartObject();
  33.                 foreach (DataColumn column in row.Table.Columns)
  34.                 {
  35.                     object columnValue = row[column];
  36.  
  37.                     if (serializer.NullValueHandling == NullValueHandling.Ignore && (columnValue == null || columnValue == DBNull.Value))
  38.                         continue;
  39.  
  40.                     writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName);
  41.                     serializer.Serialize(writer, columnValue);
  42.                 }
  43.                 writer.WriteEndObject();
  44.             }
  45.  
  46.             writer.WriteEndArray();
  47.         }
  48.  
  49.         /// <summary>
  50.         /// Reads the JSON representation of the object.
  51.         /// </summary>
  52.         /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
  53.         /// <param name="objectType">Type of the object.</param>
  54.         /// <param name="existingValue">The existing value of object being read.</param>
  55.         /// <param name="serializer">The calling serializer.</param>
  56.         /// <returns>The object value.</returns>
  57.         public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  58.         {
  59.             if (reader.TokenType == JsonToken.Null)
  60.             {
  61.                 return null;
  62.             }
  63.  
  64.             DataTable dt = existingValue as DataTable;
  65.  
  66.             if (dt == null)
  67.             {
  68.                 // handle typed datasets
  69.                 dt = (objectType == typeof(DataTable))
  70.                     ? new DataTable()
  71.                     : (DataTable)Activator.CreateInstance(objectType);
  72.             }
  73.  
  74.             // DataTable is inside a DataSet
  75.             // populate the name from the property name
  76.             if (reader.TokenType == JsonToken.PropertyName)
  77.             {
  78.                 dt.TableName = (string)reader.Value;
  79.  
  80.                 CheckedRead(reader);
  81.  
  82.                 if (reader.TokenType == JsonToken.Null)
  83.                 {
  84.                     return dt;
  85.                 }
  86.             }
  87.  
  88.             if (reader.TokenType != JsonToken.StartArray)
  89.             {
  90.                 throw new JsonSerializationException(string.Format("Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.", reader.TokenType));
  91.             }
  92.  
  93.             CheckedRead(reader);
  94.  
  95.             while (reader.TokenType != JsonToken.EndArray)
  96.             {
  97.                 CreateRow(reader, dt, serializer);
  98.  
  99.                 CheckedRead(reader);
  100.             }
  101.  
  102.             return dt;
  103.         }
  104.  
  105.         private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer serializer)
  106.         {
  107.             DataRow dr = dt.NewRow();
  108.             CheckedRead(reader);
  109.  
  110.             while (reader.TokenType == JsonToken.PropertyName)
  111.             {
  112.                 string columnName = (string)reader.Value;
  113.  
  114.                 CheckedRead(reader);
  115.  
  116.                 DataColumn column = dt.Columns[columnName];
  117.                 if (column == null)
  118.                 {
  119.                     Type columnType = GetColumnDataType(reader);
  120.                     column = new DataColumn(columnName, columnType);
  121.                     dt.Columns.Add(column);
  122.                 }
  123.  
  124.                 if (column.DataType == typeof(DataTable))
  125.                 {
  126.                     if (reader.TokenType == JsonToken.StartArray)
  127.                     {
  128.                         CheckedRead(reader);
  129.                     }
  130.  
  131.                     DataTable nestedDt = new DataTable();
  132.  
  133.                     while (reader.TokenType != JsonToken.EndArray)
  134.                     {
  135.                         CreateRow(reader, nestedDt, serializer);
  136.  
  137.                         CheckedRead(reader);
  138.                     }
  139.  
  140.                     dr[columnName] = nestedDt;
  141.                 }
  142.                 else if (column.DataType.IsArray && column.DataType != typeof(byte[]))
  143.                 {
  144.                     if (reader.TokenType == JsonToken.StartArray)
  145.                     {
  146.                         CheckedRead(reader);
  147.                     }
  148.  
  149.                     List<object> o = new List<object>();
  150.  
  151.                     while (reader.TokenType != JsonToken.EndArray)
  152.                     {
  153.                         o.Add(reader.Value);
  154.                         CheckedRead(reader);
  155.                     }
  156.  
  157.                     Array destinationArray = Array.CreateInstance(column.DataType.GetElementType(), o.Count);
  158.                     Array.Copy(o.ToArray(), destinationArray, o.Count);
  159.  
  160.                     dr[columnName] = destinationArray;
  161.                 }
  162.                 else
  163.                 {
  164.                     dr[columnName] = (reader.Value != null) ? serializer.Deserialize(reader, column.DataType) : DBNull.Value;
  165.                 }
  166.  
  167.                 CheckedRead(reader);
  168.             }
  169.  
  170.             dr.EndEdit();
  171.             dt.Rows.Add(dr);
  172.         }
  173.  
  174.         private static Type GetColumnDataType(JsonReader reader)
  175.         {
  176.             JsonToken tokenType = reader.TokenType;
  177.  
  178.             switch (tokenType)
  179.             {
  180.                 case JsonToken.Integer:
  181.                 case JsonToken.Boolean:
  182.                 case JsonToken.Float:
  183.                 case JsonToken.String:
  184.                 case JsonToken.Date:
  185.                 case JsonToken.Bytes:
  186.                     return reader.ValueType;
  187.                 case JsonToken.Null:
  188.                 case JsonToken.Undefined:
  189.                     return typeof(T); // WAS typeof(string).
  190.                 case JsonToken.StartArray:
  191.                     CheckedRead(reader);
  192.                     if (reader.TokenType == JsonToken.StartObject)
  193.                     {
  194.                         return typeof (DataTable); // nested datatable
  195.                     }
  196.  
  197.                     Type arrayType = GetColumnDataType(reader);
  198.                     return arrayType.MakeArrayType();
  199.                 default:
  200.                     throw new JsonSerializationException(string.Format("Unexpected JSON token when reading DataTable: {0}", tokenType));
  201.             }
  202.         }
  203.  
  204.         private static void CheckedRead(JsonReader reader)
  205.         {
  206.             if (!reader.Read())
  207.             {
  208.                 throw new JsonSerializationException(string.Format("Unexpected end when reading DataTable."));
  209.             }
  210.         }
  211.  
  212.         /// <summary>
  213.         /// Determines whether this instance can convert the specified value type.
  214.         /// </summary>
  215.         /// <param name="valueType">Type of the value.</param>
  216.         /// <returns>
  217.         ///     <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
  218.         /// </returns>
  219.         public override bool CanConvert(Type valueType)
  220.         {
  221.             return typeof(DataTable).IsAssignableFrom(valueType);
  222.         }
  223.     }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement