Parsing a JSON Array Using JSON.Net

Parsing a JSON array using Json.Net

You can get at the data values like this:

string json = @"
[
{ ""General"" : ""At this time we do not have any frequent support requests."" },
{ ""Support"" : ""For support inquires, please see our support page."" }
]";

JArray a = JArray.Parse(json);

foreach (JObject o in a.Children<JObject>())
{
foreach (JProperty p in o.Properties())
{
string name = p.Name;
string value = (string)p.Value;
Console.WriteLine(name + " -- " + value);
}
}

Fiddle: https://dotnetfiddle.net/uox4Vt

How to parse a json array json.net

Not wanting to use classes is weird but not impossible.

var json = reader.ReadToEnd();
var objects = JsonConvert.DeserializeObject<dynamic[]>(json);
var lvi = new ListViewItem(new string[] { (string)objects[i].label, (string)objects[i].value });

Parse JSON array in JSON.NET

You need attributes help Newtonsoft.Json mapping the source to your class.

public class DeviceInfo
{
[JsonProperty("id")]
public int DeviceID { get; set; }
[JsonProperty("id_endpoint")]
public int EndpointID { get; set; }
[JsonProperty("name")]
public string DeviceName { get; set; }
[JsonProperty("minthreshold")]
public double MinThreshold { get; set; }
[JsonProperty("maxthreshold")]
public double MaxThreshold { get; set; }
[JsonProperty("value")]
public double CurrentValue { get; set; }
[JsonProperty("time")]
public DateTime ValueTime { get; set; }
[JsonProperty("address")]
public string EndpointAddress { get; set; }
[JsonProperty("id_user")]
public int IDUser { get; set; }
}

And an outer class which your json was wrapped.

public class RootObject
{
public List<DeviceInfo> Result { get; set; }
public int StatusCode { get; set; }
}

Finally, you can use JsonConvert to Deserialize your json.

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

C# Parsing JSON array of objects

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

Parsing Multidimensional JSON Array with Name Value Pairs using Newtonsoft Json.NET

What you have here is not a multidimensional array. Instead, what you have is a collection of properties of a collection of objects presented as a flat list. If I format your JSON string for readability, it looks like:

[
"ship5",
[{"row":4,"col":6},{"row":5,"col":6},{"row":6,"col":6}],
"ship4",
[{"row":3,"col":8},{"row":3,"col":9},{"row":3,"col":10},{"row":3,"col":11}],
"ship3",
[{"row":8,"col":2},{"row":8,"col":3},{"row":8,"col":4},{"row":8,"col":5}],
"ship2",
[{"row":9,"col":7},{"row":9,"col":8},{"row":9,"col":9},{"row":9,"col":10},{"row":9,"col":11}],
"ship1",
[{"row":0,"col":0},{"row":0,"col":1},{"row":0,"col":2},{"row":0,"col":3},{"row":0,"col":4},{"row":0,"col":5}],
"ship0",
[{"row":12,"col":5},{"row":12,"col":6},{"row":12,"col":7},{"row":12,"col":8},{"row":12,"col":9},{"row":13,"col":5},{"row":13,"col":6},{"row":13,"col":7},{"row":13,"col":8},{"row":13,"col":9}]
]

With proper formatting, we can now see this fits the following pattern:

[
Object1Property1Value,
Object1Property2Value,

Object2Property1Value,
Object2Property2Value,

Object3Property1Value,
Object3Property2Value,
]

What you would like to do is to deserialize this flat list of properties to a List<T> for some type T that has the properties corresponding to the values for a single portion of the flat list above.

Firstly, I would say that this is not a particularly good way to represent your data. The structure of the JSON should reflect the structure of the data, which is not true in this case. A better format would be as a list of JSON objects, or at worst as an array of arrays of values of each object (in which case you could use Json.NET to deserialize your JSON, making use of ObjectToArrayConverter<CoordPointsArray> from Parsing JSON into C# Object - Get Properties Dynamically.)

That being said, if you cannot change the JSON format, this JSON can be deserialized successfully using Json.NET via a custom JsonConverter. First, define your data model as follows:

public class CoordPoint
{
public int row { get; set; }
public int col { get; set; }
}

public class CoordPointsArray
{
[JsonProperty(Order = 1)]
public string Name { get; set; }

[JsonProperty(Order = 2)]
public List<CoordPoint> Coordinates { get; set; }
}

Notice the [JsonProperty(Order = X)] attributes? Those will indicate to the custom converter the order in which the property values will appear in the JSON.

Next, define the following converter:

public class ObjectListToSequentialPropertyArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(T) == objectType.GetListType();
}

static bool ShouldSkip(JsonProperty property)
{
return property.Ignored || !property.Readable || !property.Writable;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var objectType = value.GetType();
var itemType = objectType.GetListType();
if (itemType == null)
throw new ArgumentException(objectType.ToString());
var itemContract = serializer.ContractResolver.ResolveContract(itemType) as JsonObjectContract;
if (itemContract == null)
throw new JsonSerializationException("invalid type " + objectType.FullName);
var list = (IList)value;
var propertyList = list
.OfType<Object>()
.Where(i => i != null) // Or should we throw an exception?
.SelectMany(i => itemContract.Properties.Where(p => !ShouldSkip(p)).Select(p => p.ValueProvider.GetValue(i)));
serializer.Serialize(writer, propertyList);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var itemType = objectType.GetListType();
if (itemType == null)
throw new ArgumentException(objectType.ToString());
if (reader.TokenType == JsonToken.Null)
return null;
var array = JArray.Load(reader);
var listContract = serializer.ContractResolver.ResolveContract(objectType) as JsonArrayContract;
var itemContract = serializer.ContractResolver.ResolveContract(itemType) as JsonObjectContract;
if (itemContract == null || listContract == null)
throw new JsonSerializationException("invalid type " + objectType.FullName);
var list = existingValue as IList ?? (IList)listContract.DefaultCreator();
var properties = itemContract.Properties.Where(p => !ShouldSkip(p)).ToArray();

for (int startIndex = 0; startIndex < array.Count; startIndex += properties.Length)
{
var item = itemContract.DefaultCreator();
for (int iProperty = 0; iProperty < properties.Length; iProperty++)
{
if (startIndex + iProperty >= array.Count)
break;
var propertyValue = array[startIndex + iProperty].ToObject(properties[iProperty].PropertyType, serializer);
properties[iProperty].ValueProvider.SetValue(item, propertyValue);
}
list.Add(item);
}
return list;
}
}

public static class TypeExtensions
{
public static Type GetListType(this Type type)
{
while (type != null)
{
if (type.IsGenericType)
{
var genType = type.GetGenericTypeDefinition();
if (genType == typeof(List<>))
return type.GetGenericArguments()[0];
}
type = type.BaseType;
}
return null;
}
}

Finally, deserialize your JSON as follows:

var settings = new JsonSerializerSettings
{
Converters = { new ObjectListToSequentialPropertyArrayConverter<CoordPointsArray>() },
};

var root = JsonConvert.DeserializeObject<List<CoordPointsArray>>(json, settings);

Working .Net fiddle showing deserialization and re-serialization to this format.

Note I have tested this with Json.NET versions 10 (the current version) and 6 (on https://dotnetfiddle.net/) but not 4.5.8.

How to parse json array with Newtonsoft.Json?

That's not a JSON array - it's just a JSON object which happens to have numbers for the properties of the response object.

You can parse it as a JObject, or deserialize it to a class like this:

public class Root
{
public int ErrorCode { get; set; }
public Dictionary<string, Entry> Response { get; set; }
}

public class Entry
{
public string Id { get; set; }
public string Name { get; set; }
}

...

Root root = JsonConvert.DeserializeObject<Root>(json);

Parsing JSON using Json.net

I don't know about JSON.NET, but it works fine with JavaScriptSerializer from System.Web.Extensions.dll (.NET 3.5 SP1):

using System.Collections.Generic;
using System.Web.Script.Serialization;
public class NameTypePair
{
public string OBJECT_NAME { get; set; }
public string OBJECT_TYPE { get; set; }
}
public enum PositionType { none, point }
public class Ref
{
public int id { get; set; }
}
public class SubObject
{
public NameTypePair attributes { get; set; }
public Position position { get; set; }
}
public class Position
{
public int x { get; set; }
public int y { get; set; }
}
public class Foo
{
public Foo() { objects = new List<SubObject>(); }
public string displayFieldName { get; set; }
public NameTypePair fieldAliases { get; set; }
public PositionType positionType { get; set; }
public Ref reference { get; set; }
public List<SubObject> objects { get; set; }
}
static class Program
{

const string json = @"{
""displayFieldName"" : ""OBJECT_NAME"",
""fieldAliases"" : {
""OBJECT_NAME"" : ""OBJECT_NAME"",
""OBJECT_TYPE"" : ""OBJECT_TYPE""
},
""positionType"" : ""point"",
""reference"" : {
""id"" : 1111
},
""objects"" : [
{
""attributes"" : {
""OBJECT_NAME"" : ""test name"",
""OBJECT_TYPE"" : ""test type""
},
""position"" :
{
""x"" : 5,
""y"" : 7
}
}
]
}";

static void Main()
{
JavaScriptSerializer ser = new JavaScriptSerializer();
Foo foo = ser.Deserialize<Foo>(json);
}

}

Edit:

Json.NET works using the same JSON and classes.

Foo foo = JsonConvert.DeserializeObject<Foo>(json);

Link: Serializing and Deserializing JSON with Json.NET



Related Topics



Leave a reply



Submit