Я пытаюсь преобразовать .NET DataTable в файл JSON и затем десериализовать файл JSON обратно в DataTable. Справедливости ради я подумал.deserialize datatable с отсутствующим первым столбцом
Однако у меня есть таблица, 3 строки по 3 столбца, каждый элемент имеет тип double. Если любое значение в первой строке равно NULL, когда JSON.Net десериализует json-файл в объект DataTable, все значения столбца, который был пустым в первой строке, становятся строками.
Чтобы быть ясным, это только если значение в первой строке равно null, что это происходит. Если любые значения равны нулю в любой другой строке, чем первая, остальные значения в этом столбце остаются удвоенными.
Если я заменяю нуль двойным, все работает как ожидалось (однако я не могу это сделать в моем случае).
Если установить NullValueHandling = NullValueHandling.Ignore, все значения оставались в парном разряде, за исключением первой строки в настоящее время получает перечисленные в последней строке:
Пример:
"Column2": 1.0,
"Column3": 1.1
},
{
"Column1": 0.0,
"Column2": 0.5,
"Column3": 2.0
},
становится:
"Column2": 1.0,
"Column3": 1.1
},
{
"Column2": 0.5,
"Column3": 2.0,
"Column1": 0.0
},
Мне нужно, чтобы десериализовать JSON, держать колонны в порядке, nd не имеют нулевых значений в первой строке, поэтому все значения в этой строке становятся строками. Мне также нужно оставить столбец 1 первой строки (в приведенном выше случае) нулевым - не волнует, является ли она пустой строкой или DBNull.
Любые мысли? (Мой тестовый код below..comment/раскомментировать NullValueHandling увидеть проблему)
DataTable table = new DataTable("MyTable");
table.Columns.Add("Column1", typeof(double));
table.Columns.Add("Column2", typeof(double));
table.Columns.Add("Column3", typeof(double));
for (int i = 0; i < 10; i++) {
if (i == 0)
table.Rows.Add(null, 1.0, 1.1);
else
table.Rows.Add(0.0, 0.5, 2.0);
}
JsonSerializer serializer = new JsonSerializer();
//serializer.TypeNameHandling = TypeNameHandling.All;
serializer.NullValueHandling = NullValueHandling.Ignore;
using (StreamWriter sw1 = new StreamWriter("1st.json"))
using (JsonWriter writer1 = new JsonTextWriter(sw1))
{
writer1.Formatting = Formatting.Indented;
serializer.Serialize(writer1, table);
}
DataTable newtable;
using (StreamReader sr = new StreamReader("1st.json"))
using (JsonReader reader = new JsonTextReader(sr))
{
newtable = (DataTable)serializer.Deserialize(reader, typeof(DataTable));
}
using (StreamWriter sw = new StreamWriter("3rd.json"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
serializer.Serialize(writer, newtable);
}
Я бы предложил вам создать класс и сериализовать/де-сериализовать в него вместо DataTable, если это возможно. – Jag
Спасибо за предложение, но это невозможно в количестве времени, которое я должен преобразовать 100k строк кода проекта из XML в json, когда DataTable бросается на весь проект (это был ужасный дизайн, но вы не знаете, всегда выбирайте). Тем временем я буду экспериментировать с несколькими другими библиотеками json. Надеюсь, у кого-то есть идея. Я просто буду доволен тем, «почему» это происходит. Кстати ... код, приведенный выше, является неловко простым примером, который я написал, чтобы проверить, что это JSON.net, а не какое-то другое взаимодействие в кодовой базе. Массив или список 2-го уровня будет проще. – Dime
Json.NET является открытым исходным кодом в соответствии с [лицензией MIT] (https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md), поэтому вы можете скопировать и изменить его код. Создайте версию ['DataTableConverter'] (https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DataTableConverter.cs), называемую, например,' DoubleDataTableConverter', в которой 'static Тип GetColumnDataType (читатель JsonReader)' возвращает 'typeof (double)' для нулевого значения. – dbc