【问题标题】:How to deserialize a json array more simply?如何更简单地反序列化 json 数组?
【发布时间】:2021-07-13 07:01:30
【问题描述】:

有没有办法只取数据集中的数据而忽略起始数组'result'?

{
    "result": [
        "",
        {
            "dataset": [
                {
                    "idSottogruppo": "7",
                    "Sottogruppo": "Distribuzione Ausiliaria"
                }, {
                    "idSottogruppo": "6",
                    "Sottogruppo": "Distribuzione Motore"
                }, {
                    "idSottogruppo": "8",
                    "Sottogruppo": "Filtri"
                }, {
                    "idSottogruppo": "39",
                    "Sottogruppo": "Motore"
                }
            ]
        }
    ]
}

我就是这样做的,而且它有效,如果可能的话,我只想减少代码,因为所有 API 方法都具有相同的 JSON 格式。

我的代码:

public class OE_GetActiveSubGroupsResultDTO
{
    public List<OE_GetSubActiveGroupsListDTO> Result { get; set; }
}

public class OE_GetActiveSubGroupsListDTO
{
    public List<OE_GetActiveSubGroupsDTO> Dataset { get; set; }
}

public class OE_GetActiveSubGroupsDTO
{
    public string idSottogruppo { get; set; }
    public string Sottogruppo { get; set; }
}

public ActionResult ProcessSpareParts(CarViewModel vm)
{
    OE_GetActiveItemsResultDTO activeItemsResultDeserialize = JsonConvert.DeserializeObject<OE_GetActiveItemsResultDTO>(GetActiveSubGroups);
                            
    foreach(var activeItemsResult in activeItemsResultDeserialize.Result[1].Dataset)
    {
        OE_GetActiveItemsDTO activeItems = new JavaScriptSerializer().Deserialize<OE_GetActiveItemsDTO>(activeItemsResult .ToString());    
        ...
    }
}

【问题讨论】:

  • group.ToString() - 你为什么要这么做? group 定义在哪里?
  • 您使用两个完全不同的 JSON 序列化程序有什么原因吗?
  • 您根本不需要任何 DTO 类型,只需使用 JToken 图形和 Linq 来提取数据。
  • @Dai 编辑了“群”

标签: c# asp.net-mvc json.net javascriptserializer


【解决方案1】:

如果您使用的是 JSON.NET,那么您应该将 JSON 文本读入 JToken 图形,然后遍历图形以提取内部 dataset - 这样您就不需要包装器/外部DTO 类型。

然后您可以使用 Linq 将数据从 JArray 中的 JObjects 提取到 List-of-Tuples:

public static JArray? GetDatasetFromJson( String jsonText )
{
    JToken root = JToken.Parse( jsonText );
    
    if( root is JObject rootObj && rootObj.TryGetValue("result", out JToken? resultArr ) && resultArr is JArray ra )
    {
        if( ra.Count == 2 )
        {
            if( ra[1] is JObject datasetWrapper )
            {
                if( datasetWrapper.TryGetValue( "dataset", out JToken? datasetTok ) && datasetTok is JArray dataset )
                {
                    return dataset;
                }
            
            }
        }
    }

    return null;
}

public static List<(String id, String value)> GetDataSetItems( JArray arr )
{
    return arr
        .OfType<JObject>()
        .Select( e => ( id: e["idSottogruppo"], value: e["Sottogruppo"] ) )
        .ToList();
}

public static void Main()
{
    String jsonText = @"""result"": [ """", { ""dataset"": [ etc ]";

    JArray? dataset = GetDatasetFromJson( jsonText );

    if( dataset is null )
    {
        throw new InvalidOperationException( "Couldn't find dataset array in JSON." )
    }

    List<(String id, String value)> items = GetDataSetItems( dataset );
}

在 Linqpad 中给我这个输出:

【讨论】:

    【解决方案2】:

    这是一行代码

    注意:此代码不对输入数据进行任何验证。如果 json 的格式没有改变,则此代码有效

    string json = File.ReadAllText("json1.json");
    
    var result = JObject.Parse(json)["result"][0]
                        .Next["dataset"]
                        .Select(x => new OE_GetActiveSubGroupsDTO 
                        { 
                                idSottogruppo = x["idSottogruppo"].ToString(), 
                                Sottogruppo = x["Sottogruppo"].ToString() 
                        });
    

    【讨论】:

    • 好点@Dai,我已经修改了我的帖子。是的,你是对的,我假设输入数据保持不变
    • @谢谢你做出的改变,我收回了我的批评:)
    猜你喜欢
    • 2021-07-11
    • 2021-09-10
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多