人们并不总是知道反序列化的类型。 因此,能够采用任何JSON(包含某些数组)并从中动态生成表将很方便。
但是,如果反序列化器不知道在哪里查找要列表的数组,则可能会出现问题。 发生这种情况时,我们将收到类似于以下内容的错误消息:
读取DataTable时出现意外的JSON令牌。 应该是StartArray,得到了StartObject。 路径'',第1行,位置1。
即使我们给予鼓励或相应地准备我们的json,数组中的“对象”类型仍然可以防止制表的发生,在这种情况下,反序列化器不知道如何用行等表示对象。在这种情况下 ,发生类似于以下错误:
读取DataTable:StartObject时,出现意外的JSON令牌。 路径'[0] .__ metadata',第3行,位置19。
以下示例JSON包含这两个有问题的功能:
{
"results":
[
{
"Enabled": true,
"Id": 106,
"Name": "item 1",
},
{
"Enabled": false,
"Id": 107,
"Name": "item 2",
"__metadata": { "Id": 4013 }
}
]
}
那么我们如何解决这个问题,又保持不知道序列化类型的灵活性?
好吧,这是我想到的一种简单方法(假设您很高兴忽略对象类型的属性,例如上例中的__metadata):
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Linq;
...
public static DataTable Tabulate(string json)
{
var jsonLinq = JObject.Parse(json);
// Find the first array using Linq
var srcArray = jsonLinq.Descendants().Where(d => d is JArray).First();
var trgArray = new JArray();
foreach (JObject row in srcArray.Children())
{
var cleanRow = new JObject();
foreach (JProperty column in row.Properties())
{
// Only include JValue types
if (column.Value is JValue)
{
cleanRow.Add(column.Name, column.Value);
}
}
trgArray.Add(cleanRow);
}
return JsonConvert.DeserializeObject(trgArray.ToString());
}
我知道这可能更像是“ LINQy”,并且具有绝对零的异常处理,但是希望可以传达这个概念。
我们开始在工作中使用越来越多的服务,这些服务会吐回JSON,因此,我很乐意让自己摆脱强力键入所有内容的负担,因为我很懒!