staff614
staff614

Reputation: 91

How to deserialize a json array more simply?

Is there some way to take only the data from the dataset and ignore the start array 'result' ?

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

That's how I did it and it works, I just want to do less code if it's possible as all API methods have the same JSON format.

My Code:

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());    
        ...
    }
}

Upvotes: 0

Views: 284

Answers (2)

Krishna Varma
Krishna Varma

Reputation: 4260

Here is the one line code

Note: this code doesn't do any validation to Input data. This code works if the format of the json doesn't change

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

Upvotes: 1

Dai
Dai

Reputation: 155145

If you're using JSON.NET, then you should read the JSON text into a JToken graph, and then traverse the graph to extract the inner dataset - that way you don't need the wrapper/outer DTO types.

Then you can use Linq to extract data from the JObjects in the JArray to a 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 );
}

Gives me this output in Linqpad:

enter image description here

Upvotes: 2

Related Questions