Я пытаюсь сериализовать / десериализовать .NET DataSet, используя Json.NET и пользовательский сериализатор.Я знаю, что многие из вас скажут мне не делать этого (я видел это на других постах). У меня есть веская причина и я хочу продолжить этот путь.
Моя сериализация основана на том факте, что .NET DataSetможет экспортировать свою схему и данные в XML, а затем повторно импортировать то же самое;Исходя из этого, я пытаюсь создать конвертер, который позволит мне захватывать этот XML, конвертировать его в JSON, затем конвертировать обратно и перезагружать.Моя реализация выглядит следующим образом ...
class DataSetConverter : JsonConverter<DataSet>
{
public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
{
DataSet dataSet = new DataSet();
JObject jObject = JObject.Load(reader);
String json = jObject.ToString();
XDocument document = JsonConvert.DeserializeXNode(json);
using (MemoryStream memoryStream = new MemoryStream())
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
streamWriter.Write(document.ToString(SaveOptions.None));
streamWriter.Flush();
memoryStream.Position = 0;
dataSet.ReadXml(memoryStream);
}
return dataSet;
}
public override void WriteJson(JsonWriter writer, DataSet dataSet, JsonSerializer serializer)
{
using (MemoryStream memoryStream = new MemoryStream())
{
dataSet.WriteXml(memoryStream, XmlWriteMode.WriteSchema);
using (StreamReader reader = new StreamReader(memoryStream))
{
memoryStream.Seek(0, SeekOrigin.Begin);
XDocument document = XDocument.Parse(reader.ReadToEnd());
writer.WriteRaw(JsonConvert.SerializeXNode(document, Formatting.Indented, false));
}
}
}
}
Используется следующим образом (чисто сериализация объекта DataSet), он работает (мой новый DataSet имеет ту же схему и данные, что и оригинал) ...
DataSet originalInserts = new DataSet("Inserts");
DataTable originalStuff = originalInserts.Tables.Add("Stuff");
originalStuff.Columns.Add("C1", typeof(String));
originalStuff.Columns.Add("C2", typeof(Int64));
originalStuff.Columns.Add("C3", typeof(Guid));
originalStuff.Columns.Add("C4", typeof(float));
originalStuff.Rows.Add("One", 2, Guid.NewGuid(), 4.4);
String json = JsonConvert.SerializeObject(originalInserts, Formatting.Indented, new DataSetConverter());
DataSet newInsertsFromConvertedXml = (DataSet)JsonConvert.DeserializeObject(json, typeof(DataSet), new DataSetConverter());
Однако, если я тогда попытаюсь использовать тот же конвертер с объектом, который содержит DataSet
(тот же DataSet
, как указано выше) ...
public class TestClass
{
public DataSet Inserts { get; set; }
public String SomethingElse { get; set; }
}
TestClass testClass = new TestClass { Inserts = originalInserts, SomethingElse = "Me" };
json = JsonConvert.SerializeObject(testClass, Formatting.Indented, new DataSetConverter());
Сбой при
Token PropertyName в состоянии Property приведет к неверному объекту JSON.Путь ''.
Я также пытался украсить DataSet
на TestClass
атрибутом JsonConverter
и удалить преобразователь из вызова метода Serialize, но получил тот же результат ...
public class TestClass
{
[JsonConverter(typeof(DataSetConverter))]
public DataSet Inserts { get; set; }
public String SomethingElse { get; set; }
}
TestClass testClass = new TestClass { Inserts = originalInserts, SomethingElse = "Me" };
json = JsonConvert.SerializeObject(testClass, Formatting.Indented);
Чего мне не хватает?