【问题标题】:Serialize DataTable including RowError and "column errors"序列化 DataTable,包括 RowError 和“列错误”
【发布时间】:2021-05-29 18:31:18
【问题描述】:

我想将带有 RowError 和列错误的 .NET DataTable 序列化为 JSON。我做这样的事情:

var dt = new DataTable();
dt.Columns.Add("Col1");

dt.Rows.Add("A");

dt.Rows[0].RowError = "Test row error";
dt.Rows[0].SetColumnError(0, "Test column error");

var json = JsonConvert.SerializeObject(dt);

生成的 JSON 如下所示:

[{"Col1":"A"}]

不包含 RowError 或列错误信息。

有没有办法序列化包含“错误”信息的 DataTable?

谢谢。

【问题讨论】:

  • 我从未看过它,但我认为您的序列化程序会根据它确实序列化列值的指示来不同地对待数据表,这 不是属性,但不序列化作为属性的东西,这与其他(普通)对象有所不同,其中 props 被序列化而 nonprops 不是......
  • stackoverflow.com/questions/43315700/… 看起来很有帮助/有趣

标签: c# asp.net json .net ado.net


【解决方案1】:

我想将带有 RowError 和列错误的 .NET DataTable 序列化为 JSON

如您所见,默认情况下,只有ColumnName 及其值被序列化。要包含您想要的其他属性,您可以通过编写自己的 JsonConverter 类来完成此操作,请参阅 Custom JsonConverter 了解更多信息。您需要有两个转换器,一个用于DataTable,另一个用于DataRow

*请注意,每个类都需要有这个命名空间:using Newtonsoft.Json;

CustomDataTableConverter

public class CustomDataTableConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType) => typeof(DataTable).IsAssignableFrom(objectType);

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            DataTable table = value as DataTable;
            CustomDataRowConverter converter = new CustomDataRowConverter();

            writer.WriteStartObject();

            writer.WritePropertyName("DataRows");
            writer.WriteStartArray();

            foreach (DataRow row in table.Rows)
            {
                converter.WriteJson(writer, row, serializer);
            }

            writer.WriteEndArray();
            writer.WriteEndObject();
        }
    }

CustomDataRowConverter

public class CustomDataRowConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType) => typeof(DataRow).IsAssignableFrom(objectType);

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            DataRow row = value as DataRow;
            JsonSerializer ser = new JsonSerializer();
            writer.WriteStartObject();

            // Serializes the row error property
            writer.WritePropertyName(nameof(row.RowError));
            ser.Serialize(writer, row.RowError);

            foreach (DataColumn column in row.Table.Columns)
            {
                writer.WritePropertyName(column.ColumnName);
                ser.Serialize(writer, row[column]);

                // Serialize the columns error description
                writer.WritePropertyName("ColumnError");
                ser.Serialize(writer, row.GetColumnError(column));
            }

            writer.WriteEndObject();
        }
    }

现在您已经拥有了所需的转换器,下面将介绍如何在您的情况下使用它们。请注意,我在这里添加了另一个数据行来显示差异。

 var dt = new DataTable();
 dt.Columns.Add("Col1");

 dt.Rows.Add("A");
 dt.Rows.Add("B");

 dt.Rows[0].RowError = "Test row error";
 dt.Rows[0].SetColumnError(0, "Test column error");

 dt.Rows[1].RowError = "Test row error B";
 dt.Rows[1].SetColumnError(0, "Test column error B");

 JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
 jsonSerializerSettings.Converters.Add(new CustomDataTableConverter());
 jsonSerializerSettings.Converters.Add(new CustomDataRowConverter());

 var json = JsonConvert.SerializeObject(dt, Formatting.Indented, jsonSerializerSettings);

运行时,我的输出如下所示:

{
  "DataRows": [
    {
      "RowError": "Test row error",
      "Col1": "A",
      "ColumnError": "Test column error"
    },
    {
      "RowError": "Test row error B",
      "Col1": "B",
      "ColumnError": "Test column error B"
    }
  ]
}

还有一点要记住,我没有做这个的反序列化部分,只有序列化部分,但它是相似的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 2010-11-19
    • 2019-05-17
    相关资源
    最近更新 更多