Json.NET is open source under the MIT License, so one possibility would be to create a modified version of its DataTableConverter
to suit your needs. Its source code is available here.
First, create your own forked version of this class, called, say, JsonDefaultTypeDataTableConverter<T>
. Modify the method GetColumnDataType
to return typeof(T)
for a null column value:
/// <summary>
/// Converts a <see cref="DataTable"/> to and from JSON.
/// Adapted from https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
/// </summary>
public class JsonDefaultTypeDataTableConverter<T> : JsonConverter
{
private static Type GetColumnDataType(JsonReader reader)
{
JsonToken tokenType = reader.TokenType;
switch (tokenType)
{
case JsonToken.Integer:
case JsonToken.Boolean:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Date:
case JsonToken.Bytes:
return reader.ValueType;
case JsonToken.Null:
case JsonToken.Undefined:
return typeof(T); // WAS typeof(string).
case JsonToken.StartArray:
CheckedRead(reader);
if (reader.TokenType == JsonToken.StartObject)
{
return typeof (DataTable); // nested datatable
}
Type arrayType = GetColumnDataType(reader);
return arrayType.MakeArrayType();
default:
throw new JsonSerializationException(string.Format("Unexpected JSON token when reading DataTable: {0}", tokenType));
}
}
}
You’ll also need to fix the calls to throw a JsonSerializationException
at around line 232, for instance as follows:
private static void CheckedRead(JsonReader reader)
{
if (!reader.Read())
{
throw new JsonSerializationException(string.Format("Unexpected end when reading DataTable."));
}
}
And, around line 114:
if (reader.TokenType != JsonToken.StartArray)
{
throw new JsonSerializationException(string.Format("Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.", reader.TokenType));
}
Now, given that you know your table contains columns of double
values, you can use it like this:
JsonSerializer serializer = new JsonSerializer();
//serializer.TypeNameHandling = TypeNameHandling.All;
//serializer.NullValueHandling = NullValueHandling.Ignore; -- DO NOT USE THIS OPTION.
serializer.Converters.Add(new JsonDefaultTypeDataTableConverter<double>());
Note that, in doing this, you’re not modifying the internals of Json.NET itself, you’re copying and modifying one of its set of standard converters for commonly used .Net types.
Update: full version here.