24

I have an array of objects like this in json format:

{"results":[{"SwiftCode":"","City":"","BankName":"Deutsche Bank","Bankkey":"10020030","Bankcountry":"DE"},{"SwiftCode":"","City":"10891 Berlin","BankName":"Commerzbank Berlin (West)","Bankkey":"10040000","Bankcountry":"DE"}]}

What I want to get is a object[] in C#, where one object contains all the data what is in one json object. The thing is, I can NOT make a class with the properties of this object like here:

public class Result
{
    public int SwiftCode { get; set; }
    public string City { get; set; }
    //      .
    //      .
    public string Bankcountry { get; set; }
}

Because I get everytime different results back, but I know it's always an array of objects. Someone knows how I could manage to get an array of objects back?

EDIT

I have to pass this object to powershell via WriteObject(results). So the ouput should only be the object IN the array.

Patrick
  • 621
  • 2
  • 7
  • 21
  • 1
    the better question is, why do you need it to be an `object[]` in c# if you don't even know what the object is going to look like? It sounds like you should be using something like a dictionary instead. – Red Alert Nov 11 '13 at 15:58
  • I don't have to know what kind of object it is, I give it over in powershell for the end-user. – Patrick Nov 11 '13 at 16:01

6 Answers6

22

Though this is an old question, I thought I'd post my answer anyway, if that helps someone in future

 JArray array = JArray.Parse(jsonString);
 foreach (JObject obj in array.Children<JObject>())
 {
     foreach (JProperty singleProp in obj.Properties())
     {
         string name = singleProp.Name;
         string value = singleProp.Value.ToString();
         //Do something with name and value
         //System.Windows.MessageBox.Show("name is "+name+" and value is "+value);
      }
 }

This solution uses Newtonsoft library, don't forget to include using Newtonsoft.Json.Linq;

Bibaswann Bandyopadhyay
  • 3,389
  • 2
  • 31
  • 30
20

Use newtonsoft like so:

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;

class Program
{
    static void Main()
    {
        string json = "{'results':[{'SwiftCode':'','City':'','BankName':'Deutsche    Bank','Bankkey':'10020030','Bankcountry':'DE'},{'SwiftCode':'','City':'10891    Berlin','BankName':'Commerzbank Berlin (West)','Bankkey':'10040000','Bankcountry':'DE'}]}";

        var resultObjects = AllChildren(JObject.Parse(json))
            .First(c => c.Type == JTokenType.Array && c.Path.Contains("results"))
            .Children<JObject>();

        foreach (JObject result in resultObjects) {
            foreach (JProperty property in result.Properties()) {
                // do something with the property belonging to result
            }
        }
    }

    // recursively yield all children of json
    private static IEnumerable<JToken> AllChildren(JToken json)
    {
        foreach (var c in json.Children()) {
            yield return c;
            foreach (var cc in AllChildren(c)) {
                yield return cc;
            }
        }
    }
}
allonhadaya
  • 1,297
  • 7
  • 19
  • 1
    Thanks for the answer, it' helpful as well. but what would be if my string looks like `tring json = "{'test':{'results':[{'SwiftCode':'','City':'','BankName':'Deutsche Bank','Bankkey':'10020030','Bankcountry':'DE'},{'SwiftCode':'','City':'10891 Berlin','BankName':'Commerzbank Berlin (West)','Bankkey':'10040000','Bankcountry':'DE'}]}}";` – Patrick Nov 12 '13 at 11:09
  • Is the `results` array at any level of nesting the signal to spit out the enclosed objects? – allonhadaya Nov 12 '13 at 18:06
  • Yes `results` it's always the name of the `object[]` I need. Solved it with the following code: `dynamic obj = JsonConvert.DeserializeObject(json); var convert = obj.d.results.ToString(); ErrorRecord errorRecord; var result = JsonObject.ConvertFromJson(convert, out errorRecord);` Do you have a smoother solution for me? – Patrick Nov 13 '13 at 07:49
  • Now another problem appeared. Somewhere in my rawjson I have dates in unixtimestamp like this: `Date: "/Date(1382400000)/"` . But if parse the json this way, It automaticly trys to convert in a type of DateTime, but with wrong date. So can I ovverride only the part of parsing the date? It would help me a lot. – Patrick Feb 04 '14 at 11:27
  • 1
    @AstralisSomnium this might lead you in the right direction: http://stackoverflow.com/questions/18088406/how-to-deserialize-date-milliseconds-with-json-net – allonhadaya Feb 05 '14 at 12:18
  • What if you have same array multiple times in a json? and you don't want to only capture the "First" occurrence.? rather want to capture all of them and add them in a array response? – shab Feb 17 '17 at 03:25
  • @shab You can use [Where](https://msdn.microsoft.com/en-us/library/system.linq.enumerable.where(v=vs.110).aspx) to capture every match instead of just the `First`. And then flatten all of their children with [SelectMany](https://msdn.microsoft.com/en-us/library/bb534336(v=vs.110).aspx): `AllChildren(...).Where(...).SelectMany(arr => .Children())` Hope that gives you some ideas. – allonhadaya Mar 04 '17 at 01:40
18

Use NewtonSoft JSON.Net library.

dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);

Hope this helps.

Mehmet Ince
  • 4,059
  • 12
  • 45
  • 65
Marvin Smit
  • 4,088
  • 1
  • 22
  • 21
  • Thanks for the fast answer. I already tried `dynamic`, but it stores even information about the array itself (like type, has valuse, first, last, parent....), but I don't need any of these. I only need the `objects`. – Patrick Nov 11 '13 at 16:04
  • 3
    So, ignore the data your not interested in and take it from obj.results[x]? – Marvin Smit Nov 11 '13 at 16:05
  • 3
    Holy potato, that's awesome! Didn't know that I can just .whateverIwantHere in a `dynamic` class. Thank you Marvin! – Patrick Nov 11 '13 at 16:08
13

I have just got an solution a little bit easier do get an list out of an JSON object. Hope this can help.

I got an JSON like this:

{"Accounts":"[{\"bank\":\"Itau\",\"account\":\"456\",\"agency\":\"0444\",\"digit\":\"5\"}]"}

And made some types like this

    public class FinancialData
{
    public string Accounts { get; set; } // this will store the JSON string
    public List<Accounts> AccountsList { get; set; } // this will be the actually list. 
}

    public class Accounts
{
    public string bank { get; set; }
    public string account { get; set; }
    public string agency { get; set; }
    public string digit { get; set; }

}

and the "magic" part

 Models.FinancialData financialData = (Models.FinancialData)JsonConvert.DeserializeObject(myJSON,typeof(Models.FinancialData));
        var accounts = JsonConvert.DeserializeObject(financialData.Accounts) as JArray;

        foreach (var account in  accounts)
        {
            if (financialData.AccountsList == null)
            {
                financialData.AccountsList = new List<Models.Accounts>();
            }

            financialData.AccountsList.Add(JsonConvert.DeserializeObject<Models.Accounts>(account.ToString()));
        }
Luiz Paulo
  • 401
  • 6
  • 14
  • 3
    This is actually the correct way of parsing a json collection inside the parent json object. – Kshitij Jhangra Feb 12 '20 at 06:47
  • I was creating all sorts of kludgy solutions that weren't working. I _knew_ there'd be a simple, elegant solution to fetching the records within a single JSON field. Thank you! – Bob Kaufman Dec 28 '20 at 19:24
2

Using .NET 6 you could use built in System.Text.Json.Nodes

Example:

string json = @"{""results"":[{""SwiftCode"":"""",""City"":"""",""BankName"":""Deutsche Bank"",""Bankkey"":""10020030"",""Bankcountry"":""DE""},{""SwiftCode"":"""",""City"":""10891 Berlin"",""BankName"":""Commerzbank Berlin (West)"",""Bankkey"":""10040000"",""Bankcountry"":""DE""}]}";

JsonObject obj = JsonNode.Parse(json).AsObject();
JsonArray jsonArray = (JsonArray)obj["results"];

enter image description here

Ogglas
  • 62,132
  • 37
  • 328
  • 418
1

I believe this is much simpler;

dynamic obj = JObject.Parse(jsonString);
string results  = obj.results;
foreach(string result in result.Split('))
{
//Todo
}
mca
  • 124
  • 1
  • 3