JSON到数据表-如何反序列化

bxpogfeg  于 2023-02-10  发布在  其他
关注(0)|答案(2)|浏览(123)

我有一个非常简单的JSON字符串:

{
    "data": {
        "id": 33306,
        "sport": {
            "id1": "FB",
            "id2": "HB"
        }
     }
}

我不明白如何从这个字符串返回数据表。
我已经尝试使用此代码,但它不工作:

DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
svmlkihl

svmlkihl1#

必须将所有json属性扁平化,然后才能转换为DataTable

var jObj = (JObject)JObject.Parse(json)["data"];
    var properties = jObj.Properties().ToList();
    
    for (var i = 0; i < properties.Count; i++)
    {
        var prop = properties[i];
        if (prop.Value.Type == JTokenType.Object)
        {
            foreach (var p in ((JObject)prop.Value).Properties())
                jObj.Add(new JProperty(prop.Name + " " + p.Name, p.Value));
            prop.Remove();
        }
    }

    DataTable dt = new JArray { jObj }.ToObject<DataTable>();

输出

[
  {
    "id": 33306,
    "sport id1": "FB",
    "sport id2": "HB"
  }
]
3ks5zfa0

3ks5zfa02#

你需要分两步来做。
1.反序列化为结构与JSON结构匹配的. net对象
1.使用该对象的属性填充DataTable

步骤1-反序列化

我们需要定义一些类来接收反序列化后的数据,类的名称并不是特别重要(只要它们对你有意义),但是这些类的属性名称需要与JSON中对应元素的名称匹配。
首先是最外层的类,它是要反序列化的JSON的形状。

public class SomeClass
{
    public DataElement Data { get; set; }
}

现在我们需要定义DataElement的形状。

public class DataElement
{
    public int Id { get; set; }
    public SportElement Sport { get; set; }
}

现在我们需要定义SportElement的形状。

public class SportElement
{
    public string Id1 { get; set; }
    public string Id2 { get; set; }
}

上面的实现是相当严格的,并且假设JSON的形状不会随文档的不同而变化,但是,如果您希望形状会变化,例如,如果sport元素可以包含任意数量的id1id2id3、... id100等元素,那么您可以丢弃SportElement类,并使用dictionary来表示该元素。

public class DataElement
{
    public int Id { get; set; }
    public Dictionary<string, string> Sport { get; set; }
}

使用哪一种方法取决于JSON结构的可预测性(或者是否在您的控制之下)我发现使用字典是处理由第三方应用程序生成的JSON的好方法,这些应用程序不在我的控制之下,但是生成的对象并不像那些我确切知道JSON将始终是什么形状的对象那样容易处理,并且可以创建一个强-表示该形状的类型化类结构。
无论您选择哪种方法,用法都是相同的:

var deserialized = JsonConvert.DeserializeObject<SomeClass>(json);

步骤2-从对象填充DataTable

如何执行此步骤将取决于您希望DataTable的外观(问题中没有明确说明),例如,您可能希望它的外观如下所示(我认为Serge's answer将返回此结果)。
| 身份证|运动标识1|运动标识2|
| - ------|- ------|- ------|
| 小行星33306|反馈|血红蛋白|
或者(例如,如果sport元素可以包含任意数量的id1id2等元素),您可能希望它如下所示。
| 身份证|体育|
| - ------|- ------|
| 小行星33306|标识1:FB|
| 小行星33306|标识2:HB|
或者,您可能需要完全不同的表示形式。如果这是一个不完整的答案,请原谅。如果您希望使用您所期望的DataTable的外观来更新问题,那么我可以使用有关如何执行步骤2的更多详细信息来更新此答案。

相关问题