假设您正在使用
json.net,那么有一个特殊的内置转换器
DataTableConverter
,它以缩写格式输出数据表,作为行数组,其中每一行都被序列化为列名/值对,如您的问题所示。虽然也有一个用于
DataSet
的转换器,但没有针对
DataRow
的特定内置转换器。因此,当直接序列化
DataRow
时,Json.NET 将序列化
DataRow
的所有字段和属性,导致输出更冗长 - 这不是您想要的。
将DataRow序列化为DataTable使用的更紧凑形式最直接的方法是将整个表格序列化为JArray
,然后使用JArray.FromObject()
选择与要序列化的DataRow
具有相同索引的数组项:
var rowIndex = 0;
var jArray = JArray.FromObject(datatable, JsonSerializer.CreateDefault(new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
var rowJToken = jArray[rowIndex];
var rowJson = rowJToken.ToString(Formatting.Indented);
由于您的表格只有一行,rowIndex
应该是 0
。更一般地,如果您不知道给定 DataRow
的索引,则请参阅 如何从数据表中获取行号?。
这对于只有一行的表格应该很好用,但在一般情况下不会很高效。
演示 fiddle #1 在这里。
或者,如果表格有许多行但只有少数列,您可以使用 LINQ 将行转换为 Dictionary<string, object>
,然后将其序列化:
var rowJson = JsonConvert.SerializeObject(
row.Table.Columns.Cast<DataColumn>()
.ToDictionary(c => c.ColumnName, c => row.IsNull(c) ? null : row[c]),
Formatting.Indented);
只要列数不多,性能应该不会太差。
Fiddle #2
在这里。
将一行序列化为JSON的最高效方式是为
DataRow
引入一个
自定义的 JsonConverter
,以将行写入JSON对象:
public class DataRowConverter : JsonConverter<DataRow>
{
public override DataRow ReadJson(JsonReader reader, Type objectType, DataRow existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException(string.Format("{0} is only implemented for writing.", this));
}
public override void WriteJson(JsonWriter writer, DataRow row, JsonSerializer serializer)
{
var table = row.Table;
if (table == null)
throw new JsonSerializationException("no table");
var contractResolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartObject();
foreach (DataColumn col in row.Table.Columns)
{
var value = row[col];
if (serializer.NullValueHandling == NullValueHandling.Ignore && (value == null || value == DBNull.Value))
continue;
writer.WritePropertyName(contractResolver != null ? contractResolver.GetResolvedPropertyName(col.ColumnName) : col.ColumnName);
serializer.Serialize(writer, value);
}
writer.WriteEndObject();
}
}
然后像这样使用:
var settings = new JsonSerializerSettings
{
Converters = { new DataRowConverter() },
};
var rowJson = JsonConvert.SerializeObject(row, Formatting.Indented, settings);
注意:
演示fiddle #3 在这里。