1

I am trying to use an RESTFUL API for an application we use internally. One call to the API returns the following JSON:

{
    "operation": {
        "name": "GET RESOURCES",
        "result": {
            "status": "Success",
            "message": "Query was successful"
        },
        "totalRows": 2,
        "Details": [{
            "RESOURCE DESCRIPTION": "Windows",
            "RESOURCE TYPE": "Windows",
            "RESOURCE ID": "101",
            "RESOURCE NAME": "WINDOWSPC",
            "NOOFACCOUNTS": "1"
        }, {
            "RESOURCE DESCRIPTION": "Ubuntu",
            "RESOURCE TYPE": "Linux",
            "RESOURCE ID": "808",
            "RESOURCE NAME": "UBUNTUPC",
            "NOOFACCOUNTS": "2"
        }]
    }
}

Using json.net I deseralize the json and check the stats with the following lines:

dynamic json = JsonConvert.DeserializeObject(response);
var status = json.operation.result.status.Value;

Next I want to get each value of each of the "Details" returned, but I cannot figure out how. I first tried getting the Details only with this:

var resourceList = json.operation.Details

Which works, but I cannot iterate over this to get just the "RESOURCE ID" and "RESOURCE NAME" for example.

I cannot use .Children() either, but when I hover over the resourceList there is a ChildrenTokens which seems to be what I want, but I cannot get at that in my code.

I also tried using resourceList as a DataSet as per their example but it throws an exception.

Can someone see what I am doing wrong..... I am not familiar with parsing JSON in C#

11
  • 1
    Copy your JSON string then use Paste Special ( Edit -> Paste Special -> Paste JSON as Classes), it will generate all necessary classes for you. Commented Feb 10, 2020 at 12:54
  • @SᴇM that sounds like something I could use.... but in my VS2019 Community, I don't have that option... Commented Feb 10, 2020 at 12:56
  • 1
    @neildeadman you do, it's available in all editions. In a C# file, go to the Edit menu and open the Paste Special submenu. The option doesn't appear in other text files Commented Feb 10, 2020 at 12:58
  • once you have the class define you can simply use the DeserializeObject<T> with T your class. newtonsoft.com/json/help/html/DeserializeObject.htm Commented Feb 10, 2020 at 13:00
  • Does this answer your question? Deserialize JSON into Object C# Commented Feb 10, 2020 at 13:00

3 Answers 3

2

You can use Json.Linq for that and parse a response into JObject, then iterate it foreach loop. It's possible, since Details is an array and JObject implements IDictionary<string, JToken> and IEnumerable<KeyValuePair<string, JToken>>

var jObject = JObject.Parse(response);

foreach (var detail in jObject["operation"]["Details"])
{
    var description = detail["RESOURCE DESCRIPTION"].Value<string>();
    //other properties
}
Sign up to request clarification or add additional context in comments.

Comments

1

Here's an example using the JObject class instead of dynamic

JObject json = JObject.Parse(response);

string status = json["operation"]["result"]["status"].Value<string>();

foreach (JToken resource in json["operation"]["Details"])
{
    string id = resource["RESOURCE ID"].Value<string>();
    string name = resource["RESOURCE NAME"].Value<string>();
}

Comments

1

It is as simple as this:

Your Model classes would look like:

public class Result
{
    public string status { get; set; }
    public string message { get; set; }
}

public class Detail
{
    [JsonProperty("RESOURCE DESCRIPTION")]
    public string ResourceDescription { get; set; }
    [JsonProperty("RESOURCE TYPE")]
    public string ResourceType { get; set; }
    [JsonProperty("RESOURCE ID")]
    public string ResourceId { get; set; }
    [JsonProperty("RESOURCE NAME")]
    public string ResourceName { get; set; }
    [JsonProperty("NOOFACCOUNTS")]
    public string NoOfAccounts { get; set; }
}

public class Operation
{
    public string name { get; set; }
    public Result result { get; set; }
    public int totalRows { get; set; }
    public List<Detail> Details { get; set; }
}

public class RootObject
{
    public Operation operation { get; set; }
}

To de-serialize:

var json = JsonConvert.DeserializeObject<RootObject>(response);

To access a property:

var name=json.operation.name

To access your Details:

foreach(var item in json.operation.Details)
{
var myresourcename=item.ResourceName;
//So on
}

9 Comments

Thanks, the other answers are shorter, but I am going to look into this more.
@neildeadman If you want a concrete implementation of your JSON into associated Model structure, then go ahead with this.
I would use this approach as well, since you don't have to mess around with strings (less errors, IntelliSense support, etc.).
So another API call returns a different JSON that also has Operation, but is missing the TotalRows field. Am I best to implement a different class for each or can I implement multiple classes that are similar etc.
Yes, you can use this class for the other API response. Basically, you can define a Model structure for your base API response and use inheritance concept for your inner responses.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.