【问题标题】:Serializing a DataSet/DataTable with properties in json.net使用 json.net 中的属性序列化 DataSet/DataTable
【发布时间】:2014-07-14 17:36:31
【问题描述】:

我正在寻找将数据集序列化为 json 的解决方案,但我需要获取 json 中的行状态。

json.net 是否序列化/反序列化数据集/数据表的属性,例如 rowstate?我只能找到具有行值的示例。

谢谢。

【问题讨论】:

    标签: dataset json.net rowstate


    【解决方案1】:

    不,Json.Net 附带的DataTableConverter 不会序列化RowState。如果你真的需要 JSON 中的这个值,应该可以创建一个自定义的JsonConverter 来输出它。但是,由于RowState 是只读属性,因此无法将其反序列化回其原始值。 (其实这个值是通过各种内部状态变量计算出来的。)

    【讨论】:

      【解决方案2】:

      我为 DataSet 编写了一个自定义转换器,用于保持行状态。 DataSet 类可以用WriteXmlSchema 将schema 写为xml,它可以用WriteXml(sw, XmlWriteMode.DiffGram) 写包括rowstate 的数据。这会生成两个字符串,它们是 DataSetSerializer 类中的属性,然后可以使用 JsonSerializer 对其进行序列化和反序列化。这是一个测试类中的代码:

      using Microsoft.VisualStudio.TestTools.UnitTesting;
      using System;
      using System.Data;
      using System.IO;
      using System.Text.Json;
      using System.Text.Json.Serialization;
      
      namespace TestProject3
      {
          public class DataSetConverter : JsonConverter<DataSet>
          {
              private class DataSetSerializer
              {
                  public string SchemaString { get; set; }
                  public string DataString { get; set; }
                  private static string GetSchema(DataSet ds)
                  {
                      using (var sw = new StringWriter())
                      {
                          ds.WriteXmlSchema(sw);
                          return sw.ToString();
                      }
                  }
                  private static string GetData(DataSet ds)
                  {
                      using (var sw = new StringWriter())
                      {
                          ds.WriteXml(sw, XmlWriteMode.DiffGram);
                          return sw.ToString();
                      }
                  }
                  private DataSet GetDataSet()
                  {
                      var ds = new DataSet();
                      using (var sr1 = new StringReader(SchemaString))
                      {
                          ds.ReadXmlSchema(sr1);
                      }
                      using (var sr2 = new StringReader(DataString))
                      {
                          ds.ReadXml(sr2, XmlReadMode.DiffGram);
                      }
                      return ds;
                  }
                  public static string Serialize(DataSet ds)
                  {
                      var serializer = new DataSetSerializer() { SchemaString = GetSchema(ds), DataString = GetData(ds) };
                      return JsonSerializer.Serialize<DataSetSerializer>(serializer);
                  }
                  public static DataSet DeSerialize(string s)
                  {
                      var serializer = JsonSerializer.Deserialize<DataSetSerializer>(s);
                      return serializer.GetDataSet();
                  }
              }
              public override DataSet Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
              {
                  return DataSetSerializer.DeSerialize(reader.GetString());
              }
      
              public override void Write(Utf8JsonWriter writer, DataSet value, JsonSerializerOptions options)
              {
                  writer.WriteStringValue(DataSetSerializer.Serialize(value));
              }
          }
      
          [TestClass]
          public class TestDataSet
          {
              private DataSet CreateTestDataSet()
              {
                  var ds = new DataSet();
                  var dt = ds.Tables.Add();
                  dt.Columns.Add("A");
                  dt.Columns.Add("B");
                  dt.Rows.Add("A1", "B1");
                  var dr = dt.Rows.Add("A2", "B2");
                  ds.AcceptChanges();
                  dr["A"] = "AA2";
                  return ds;
              }
      
              private void CheckTestDataSet(DataSet ds)
              {
                  var dt = ds.Tables[0];
                  Assert.IsTrue(dt.Rows[0].RowState == DataRowState.Unchanged && dt.Rows[1].RowState == DataRowState.Modified);
              }
      
              [TestMethod]
              public void TestDataSetConverter()
              {
                  var ds = CreateTestDataSet();
                  var serializeOptions = new JsonSerializerOptions { Converters = { new DataSetConverter() } };
                  var jsonstring = JsonSerializer.Serialize(ds, serializeOptions);
                  ds = JsonSerializer.Deserialize<DataSet>(jsonstring, serializeOptions);
                  CheckTestDataSet(ds);
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        我需要一个解决方案,为 DataSetsDataTables 维护 RowState,以便从 SOAP 调用迁移到 WebApi 调用但使用 Newtonsoft 而不是 System.Text.Json 的遗留应用程序。谢谢Alex 的最后一个答案,这正是我所需要的。

        这是同一事物的 Newtonsoft 版本:

        using System;
        using System.Data;
        using System.IO;
        using Newtonsoft.Json;
        using Xunit;
        
        namespace DataSetsAndTablesTester
        {
            public class CustomJsonConverter_DataSet : JsonConverter<DataSet>
            {
                private class DataSetSerializer
                {
                    public string SchemaString { get; set; }
                    public string DataString { get; set; }
        
                    private static string GetSchema(DataSet ds)
                    {
                        using (var sw = new StringWriter())
                        {
                            ds.WriteXmlSchema(sw);
                            return sw.ToString();
                        }
                    }
                    private static string GetData(DataSet ds)
                    {
                        using (var sw = new StringWriter())
                        {
                            ds.WriteXml(sw, XmlWriteMode.DiffGram);
                            return sw.ToString();
                        }
                    }
                    private DataSet GetDataSet()
                    {
                        var ds = new DataSet();
                        using (var sr1 = new StringReader(SchemaString))
                        {
                            ds.ReadXmlSchema(sr1);
                        }
                        using (var sr2 = new StringReader(DataString))
                        {
                            ds.ReadXml(sr2, XmlReadMode.DiffGram);
                        }
                        return ds;
                    }
                    public static string Serialize(DataSet ds)
                    {
                        var serializer = new DataSetSerializer() { SchemaString = GetSchema(ds), DataString = GetData(ds) };
                        return JsonConvert.SerializeObject(serializer);
                    }
                    public static DataSet DeSerialize(string s)
                    {
                        var serializer = JsonConvert.DeserializeObject<DataSetSerializer>(s);
                        return serializer.GetDataSet();
                    }
                }
        
                public override void WriteJson(JsonWriter writer, DataSet value, JsonSerializer serializer)
                {
                    if (value == null)
                        throw new Exception("Passed in DataSet is null");
        
                    writer.WriteValue(DataSetSerializer.Serialize(ds: value));
                }
        
                public override DataSet ReadJson(JsonReader reader, Type objectType, DataSet existingValue, bool hasExistingValue, JsonSerializer serializer)
                {
                    return DataSetSerializer.DeSerialize((string)reader.Value);
                }
            }
        
            public class CustomJsonConverter_DataTable : JsonConverter<DataTable>
            {
                private class DataTableSerializer
                {
                    public string SchemaString { get; set; }
                    public string DataString { get; set; }
        
                    private static string GetSchema(DataTable dt)
                    {
                        using (var sw = new StringWriter())
                        {
                            dt.WriteXmlSchema(sw);
                            return sw.ToString();
                        }
                    }
                    private static string GetData(DataTable dt)
                    {
                        using (var sw = new StringWriter())
                        {
                            dt.WriteXml(sw, XmlWriteMode.DiffGram);
                            return sw.ToString();
                        }
                    }
                    private DataTable GetDataTable()
                    {
                        var dt = new DataTable();
                        using (var sr1 = new StringReader(SchemaString))
                        {
                            dt.ReadXmlSchema(sr1);
                        }
                        using (var sr2 = new StringReader(DataString))
                        {
                            dt.ReadXml(sr2);
                        }
                        return dt;
                    }
                    public static string Serialize(DataTable dt)
                    {
                        var serializer = new DataTableSerializer() { SchemaString = GetSchema(dt), DataString = GetData(dt) };
                        return JsonConvert.SerializeObject(serializer);
                    }
                    public static DataTable DeSerialize(string s)
                    {
                        var serializer = JsonConvert.DeserializeObject<DataTableSerializer>(s);
                        return serializer.GetDataTable();
                    }
                }
        
                public override void WriteJson(JsonWriter writer, DataTable value, JsonSerializer serializer)
                {
                    if (value == null)
                        throw new Exception("Passed in DataTable is null");
        
                    if (string.IsNullOrEmpty(value.TableName))
                        throw new Exception("Passed in DataTable Name is null or empty");
        
                    writer.WriteValue(DataTableSerializer.Serialize(dt: value));
                }
        
                public override DataTable ReadJson(JsonReader reader, Type objectType, DataTable existingValue, bool hasExistingValue, JsonSerializer serializer)
                {
                    return DataTableSerializer.DeSerialize((string)reader.Value);
                }
            }
        
            public class JsonConverterTester
            {
                public void TestJsonDataSetConverter()
                {
                    DataSet ds = CreateTestDataSet();
        
                    String json = JsonConvert.SerializeObject(value: ds, converters: new CustomJsonConverter_DataSet());
        
                    Console.WriteLine(json);
        
                    DataSet ds2 = JsonConvert.DeserializeObject<DataSet>(value: json, converters: new CustomJsonConverter_DataSet());
        
                    CheckTestDataSet(ds2);
                }
        
                public void TestJsonDataTableConverter()
                {
                    DataTable dt = CreateTestDataTable();
        
                    String json = JsonConvert.SerializeObject(value: dt, converters: new CustomJsonConverter_DataTable());
        
                    Console.WriteLine(json);
        
                    DataTable dt2 = JsonConvert.DeserializeObject<DataTable>(value: json, converters: new CustomJsonConverter_DataTable());
        
                    CheckTestDataTable(dt2);
                }
        
                private DataSet CreateTestDataSet()
                {
                    var ds = new DataSet();
                    var dt = ds.Tables.Add();
                    dt.Columns.Add("A");
                    dt.Columns.Add("B");
                    dt.Rows.Add("A1", "B1");
                    var dr = dt.Rows.Add("A2", "B2");
                    ds.AcceptChanges();
                    dr["A"] = "AA2";
                    return ds;
                }
        
                private void CheckTestDataSet(DataSet ds)
                {
                    var dt = ds.Tables[0];
                    Assert.True(dt.Rows[0].RowState == DataRowState.Unchanged && dt.Rows[1].RowState == DataRowState.Modified);
                }
        
                private DataTable CreateTestDataTable()
                {
                    var dt = new DataTable();
                    dt.TableName = "TestTable";
                    dt.Columns.Add("A");
                    dt.Columns.Add("B");
                    dt.Rows.Add("A1", "B1");
                    var dr = dt.Rows.Add("A2", "B2");
                    dt.AcceptChanges();
                    dr["A"] = "AA2";
                    return dt;
                }
        
                private void CheckTestDataTable(DataTable dt)
                {
                    Assert.True(dt.Rows[0].RowState == DataRowState.Unchanged && dt.Rows[1].RowState == DataRowState.Modified);
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-25
          • 2012-04-01
          • 1970-01-01
          相关资源
          最近更新 更多