本文介绍了将数据行转换为JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DataTable,它只有一行,看起来像

I have a DataTable which has only a single row and looks like

   America              |  Africa               |     Japan     |   
   -------------------------------------------------------------
  {"Id":1,"Title":"Ka"} | {"Id":2,"Title":"Sf"} | {"Id":3,"Title":"Ja","Values":{"ValID":4,"Type":"Okinawa"}} 

DataTable列是美国,非洲,日本.

The DataTable columns are America, Africa, Japan.

现在,我想将DataTable转换为JSON,以使JSON看起来像

Now I want to convert the DataTable to JSON such that the JSON looks like

{
"America": {
    "Id": 1,
    "Title": "Ka"
},
"Africa": {
    "Id": 2,
    "Title": "Sf"
},
"Japan": {
    "Id": 3,
    "Title": "Ja",
    "Values": {
        "ValID": 4,
        "Type": "Okinawa"
    }
  }
}  

我的尝试是:

string js = JSonConvverter.Serializeobject(datatable);
var objType =  JObject.Parse(js);

但是没有用.任何帮助将不胜感激.

But it didn't work. Any help would be appreciated.

推荐答案

假设您使用的是 json.net ,有一个特殊的内置转换器, DataTableConverter ,它以缩写格式作为行数组,其中每行都按问题中的列名/值对序列化.同时还有用于DataSet ,没有用于 DataRow .因此,当直接序列化DataRow时,Json.NET将序列化DataRow的所有字段和属性,从而产生更加冗长的输出-不需要.

Assuming you are using json.net, there is a special built-in converter, DataTableConverter, that outputs data tables in an abbreviated format as an array of rows where each row is serialized as column name/value pairs as shown in your question. While there is also a converter for DataSet, there is no specific built-in converter for DataRow. Thus when directly serializing a DataRow Json.NET will serialize all the fields and properties of the DataRow resulting in a more verbose output - which you do not want.

DataTable使用的更紧凑形式对DataRow进行序列化的最简单方法是使用JArray www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JArray_FromObject.htm"rel =" nofollow noreferrer> JArray.FromObject() ,然后选择与要序列化的DataRow具有相同索引的数组项:

The easiest way to serialize a DataRow in the more compact form used by DataTable is to serialize the entire table to a JArray using JArray.FromObject() and then pick out the array item with the same index as the DataRow you want to serialize:

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的索引,请参见 如何从数据表? .

Since your table has only one row, rowIndex should be 0. More generally, if you don't know the index of a given DataRow, see How to get the row number from a datatable?.

演示小提琴#1 此处.

或者,如果您的表足够大以至于序列化整个表都会影响性能,则可以引入用于DataRow的自定义JsonConverter ,它将行作为对象写入JSON:

Alternatively, if your table is large enough that serializing the entire table has performance implications, you can introduce a custom JsonConverter for DataRow that writes the row to JSON as an object:

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);

注意:

  • 虽然序列化单个DataRow是有意义的,但是反序列化却没有意义,因为DataRow不是独立的对象;它仅存在于某些父DataTable内部.因此未实现ReadJson().

  • While it makes sense to serialize a single DataRow, it doesn't make sense to deserialize one since a DataRow is not a standalone object; it exists only inside some parent DataTable. Thus ReadJson() is not implemented.

JsonConverter<T> . NET 11.0.1 .在早期版本中,它是从 JsonConverter .

JsonConverter<T> was introduces in Json.NET 11.0.1. In earlier versions inherit from JsonConverter.

演示小提琴#2 此处.

这篇关于将数据行转换为JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 01:50