user6911358 user6911358 - 2 months ago 24
C# Question

C# Deserializing JSON using json.net , want to extract array index as a model property

I am successfully deserializing a returned JSON array from a RESTful GET request into my C# plain old object model.

I am using the [JSONProperty foo] annotations to bind the JSON names to my model properties.

The JSON returned looks like this :

[{
"ProductCode": "0129923083091",
"Description": "DIESEL ",
"SalesLitres": 6058.7347,
"SalesValue": 6416.2000
},
{
"ProductCode": "0134039344902",
"Description": "UNLEADED ",
"SalesLitres": 3489.8111,
"SalesValue": 3695.7100
},
...
]


I would like to create something akin to a unique index field within my model which is synthesized based on the order of the appearance of the array items returned from JSON.

For reference, my current annotations (without the indexing property) looks like so :

namespace App8.Models
{
public class ReportRow
{
[JsonProperty("ProductCode")]
public string ProductCode { get; set; } = string.Empty;

[JsonProperty("Description")]
public string Description { get; set; } = string.Empty;

[JsonProperty("SalesLitres")]
public double SalesLitres { get; set; } = 0.0;

[JsonProperty("SalesValue")]
public double SalesValue { get; set; } = 0.0;
}
}


Is there an annotation for this provided by Newtonsoft JSON.net...
Or, is there some code which I can place within getter/setters to manufacture a primary key , in essence ?

Answer

Assuming

public class ReportRow {
    public int Index { get; set; }

    [JsonProperty("ProductCode")]
    public string ProductCode { get; set; } = string.Empty;

    [JsonProperty("Description")]
    public string Description { get; set; } = string.Empty;

    [JsonProperty("SalesLitres")]
    public double SalesLitres { get; set; } = 0.0;

    [JsonProperty("SalesValue")]
    public double SalesValue { get; set; } = 0.0;    
}

After deserializing the data

var data = JsonConvert.DeserializeObject<List<ReportRow>>(json);

You could use linq select to get indexes.

var indexedData = data.Select((item, index) => {
    item.Index = index;
    return item;
}).ToList();

Or, if index is not a property on model create a type on the fly with one.

var indexedData = data.Select((item, index) => new {
    Index = index,
    ReportRow = item
}).ToList();