假设您使用的是json.net,则有一个特殊的内置转换器DataTableConverter,它将abbreviated format 中的数据表输出为一个行数组,其中每一行被序列化为列名/值对显示在您的问题中。虽然还有a converter for DataSet,但DataRow 没有特定的内置转换器。因此,当直接序列化 DataRow 时,Json.NET 将序列化 DataRow 的所有字段和属性,从而导致更冗长的输出 - 这是您不想要的。
最简单的方法以DataTable 使用的更紧凑的形式序列化DataRow 是使用JArray.FromObject() 将整个表序列化为JArray,然后挑选出数组与您要序列化的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); // Or Formatting.None if you prefer
由于您的表只有一行,rowIndex 应该是0。更一般地说,如果您不知道给定 DataRow 的索引,请参阅 How to get the row number from a datatable?。
演示小提琴 #1 here.
或者,如果您的表足够大以至于序列化整个表会影响性能,您可以为DataRow 引入custom 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 row = datatable.Rows[rowIndex];
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Converters = { new DataRowConverter() },
};
var rowJson = JsonConvert.SerializeObject(row, Formatting.Indented, settings);
注意事项:
演示小提琴 #2 here.