As others have already pointed out, the reason you are not getting the results you expect is because your JSON does not match the class structure that you are trying to deserialize into. You either need to change your JSON or change your classes. Since others have already shown how to change the JSON, I will take the opposite approach here.
To match the JSON you posted in your question, your classes should be defined like those below. Notice I've made the following changes:
- I added a
Wrapperclass corresponding to the outer object in your JSON. - I changed the
Valuesproperty of theValueSetclass from aList<Value>to aDictionary<string, Value>since thevaluesproperty in your JSON contains an object, not an array. - I added some additional
[JsonProperty]attributes to match the property names in your JSON objects.
Class definitions:
class Wrapper
{
[JsonProperty("JsonValues")]
public ValueSet ValueSet { get; set; }
}
class ValueSet
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("values")]
public Dictionary<string, Value> Values { get; set; }
}
class Value
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("diaplayName")]
public string DisplayName { get; set; }
}
You need to deserialize into the Wrapper class, not the ValueSet class. You can then get the ValueSet from the Wrapper.
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Here is a working program to demonstrate:
class Program
{
static void Main(string[] args)
{
string jsonString = @"
{
""JsonValues"": {
""id"": ""MyID"",
""values"": {
""value1"": {
""id"": ""100"",
""diaplayName"": ""MyValue1""
},
""value2"": {
""id"": ""200"",
""diaplayName"": ""MyValue2""
}
}
}
}";
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Console.WriteLine("id: " + valueSet.Id);
foreach (KeyValuePair<string, Value> kvp in valueSet.Values)
{
Console.WriteLine(kvp.Key + " id: " + kvp.Value.Id);
Console.WriteLine(kvp.Key + " name: " + kvp.Value.DisplayName);
}
}
}
And here is the output:
id: MyID
value1 id: 100
value1 name: MyValue1
value2 id: 200
value2 name: MyValue2
Answer from Brian Rogers on Stack OverflowAs others have already pointed out, the reason you are not getting the results you expect is because your JSON does not match the class structure that you are trying to deserialize into. You either need to change your JSON or change your classes. Since others have already shown how to change the JSON, I will take the opposite approach here.
To match the JSON you posted in your question, your classes should be defined like those below. Notice I've made the following changes:
- I added a
Wrapperclass corresponding to the outer object in your JSON. - I changed the
Valuesproperty of theValueSetclass from aList<Value>to aDictionary<string, Value>since thevaluesproperty in your JSON contains an object, not an array. - I added some additional
[JsonProperty]attributes to match the property names in your JSON objects.
Class definitions:
class Wrapper
{
[JsonProperty("JsonValues")]
public ValueSet ValueSet { get; set; }
}
class ValueSet
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("values")]
public Dictionary<string, Value> Values { get; set; }
}
class Value
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("diaplayName")]
public string DisplayName { get; set; }
}
You need to deserialize into the Wrapper class, not the ValueSet class. You can then get the ValueSet from the Wrapper.
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Here is a working program to demonstrate:
class Program
{
static void Main(string[] args)
{
string jsonString = @"
{
""JsonValues"": {
""id"": ""MyID"",
""values"": {
""value1"": {
""id"": ""100"",
""diaplayName"": ""MyValue1""
},
""value2"": {
""id"": ""200"",
""diaplayName"": ""MyValue2""
}
}
}
}";
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;
Console.WriteLine("id: " + valueSet.Id);
foreach (KeyValuePair<string, Value> kvp in valueSet.Values)
{
Console.WriteLine(kvp.Key + " id: " + kvp.Value.Id);
Console.WriteLine(kvp.Key + " name: " + kvp.Value.DisplayName);
}
}
}
And here is the output:
id: MyID
value1 id: 100
value1 name: MyValue1
value2 id: 200
value2 name: MyValue2
http://json2csharp.com/
I found the above link incredibly helpful as it corrected my C# classes by generating them from the JSON that was actually returned.
Then I called :
JsonConvert.DeserializeObject<RootObject>(jsonString);
and everything worked as expected.
android - Converting JSONarray to ArrayList - Stack Overflow
[Help] JSON Array to List
Here's how to think about deserializing JSON.
There are two paths, and one is easier. The easier is to make a C# object graph that looks like the JSON object, then deserialize to it. The harder is to use the token parser or types like JObject to do the same thing with a little more effort. The harder paths are better if the JSON is really "weird" and requires special effort to get into sensible C# objects.
This isn't quite bad enough to need to use JArray. Obviously you can't make a C# object with a property named "1", "2", "3", and so on, but there's another way to go about this. Any JSON object is effectively a Dictionary<string, object>, so our first decision can be that this is our outer object.
The inner objects of this dictionary do have a well-defined type. They have four properties that are strings, though maybe for your logic "id" will be a number. So we can make an object to represent this and have a more specific Dictionary.
So I'd start with:
public class JsonTask
{
public string Id { get; set; }
public string Entrant { get; set; }
public string Recipient { get; set; }
public string Task { get; set; }
}Then the code to get the dictionary is:
var dict = JsonConvert.DeserializeObject<Dictionary<string, JsonTask>>(json);
From there, getting an array could be:
var asArray = dict.Values.ToArray();
If order is super important, you might have to do something more complex. If you know all the properties are always sequential integers, a for loop over Keys is good enough. If they might not be ordered, you might try converting Keys to an array, sorting it, then using each key to fetch each value.
I don't think the other comment about deserializing to a list will work, generally you can only deserialize JSON arrays to lists, and this is more of an object being used as a dictionary.
More on reddit.comHow to convert JSON array into object list in the c# - Stack Overflow
apex - JSON Array String into List - Salesforce Stack Exchange
Videos
ArrayList<String> listdata = new ArrayList<String>();
JSONArray jArray = (JSONArray)jsonObject;
if (jArray != null) {
for (int i=0;i<jArray.length();i++){
listdata.add(jArray.getString(i));
}
}
I've done it using Gson (by Google).
Add the following line to your module's build.gradle:
dependencies {
// ...
// Note that `compile` will be deprecated. Use `implementation` instead.
// See https://stackoverflow.com/a/44409111 for more info
implementation 'com.google.code.gson:gson:2.8.2'
}
JSON string:
private String jsonString = "[\n" +
" {\n" +
" \"id\": \"c200\",\n" +
" \"name\": \"Ravi Tamada\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c201\",\n" +
" \"name\": \"Johnny Depp\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c202\",\n" +
" \"name\": \"Leonardo Dicaprio\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c203\",\n" +
" \"name\": \"John Wayne\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c204\",\n" +
" \"name\": \"Angelina Jolie\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"female\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c205\",\n" +
" \"name\": \"Dido\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"female\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c206\",\n" +
" \"name\": \"Adele\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"female\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c207\",\n" +
" \"name\": \"Hugh Jackman\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c208\",\n" +
" \"name\": \"Will Smith\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c209\",\n" +
" \"name\": \"Clint Eastwood\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c2010\",\n" +
" \"name\": \"Barack Obama\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c2011\",\n" +
" \"name\": \"Kate Winslet\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"female\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"id\": \"c2012\",\n" +
" \"name\": \"Eminem\",\n" +
" \"email\": \"[email protected]\",\n" +
" \"address\": \"xx-xx-xxxx,x - street, x - country\",\n" +
" \"gender\" : \"male\",\n" +
" \"phone\": {\n" +
" \"mobile\": \"+91 0000000000\",\n" +
" \"home\": \"00 000000\",\n" +
" \"office\": \"00 000000\"\n" +
" }\n" +
" }\n" +
" ]";
ContactModel.java:
public class ContactModel {
public String id;
public String name;
public String email;
}
Code for converting a JSON string to ArrayList<Model>:
Note: You have to import java.lang.reflect.Type;:
// Top of file
import java.lang.reflect.Type;
// ...
private void parseJSON() {
Gson gson = new Gson();
Type type = new TypeToken<List<ContactModel>>(){}.getType();
List<ContactModel> contactList = gson.fromJson(jsonString, type);
for (ContactModel contact : contactList){
Log.i("Contact Details", contact.id + "-" + contact.name + "-" + contact.email);
}
}
Hope this will help you.
Hi all,
I'm playing around with JSON and I have a JSON array that I'd like to add into a Listbox. I've only ever used a single JSON before and I'm not sure how to do it with a JSON Array using NewtonSoft.
{
"1": {
"id": "628190",
"entrant": "ENTRANT NAME",
"recipient": "RECIPIENT NAME",
"task": "Task Description"
}
"2": {
"id": "628191",
"entrant": "ENTRANT NAME",
"recipient": "RECIPIENT NAME",
"task": "Task Description"
}
"3": {
"id": "628192",
"entrant": "ENTRANT NAME",
"recipient": "RECIPIENT NAME",
"task": "Task Description"
}
}I know I'm missing a foreach or something like that. In the past I've only done something like this:
{
"description": "Some description",
"reason": "Some reason"
}and I've just used this
Details detail = JsonConvert.DeserializeObject<Details>(webResult1);
Here's how to think about deserializing JSON.
There are two paths, and one is easier. The easier is to make a C# object graph that looks like the JSON object, then deserialize to it. The harder is to use the token parser or types like JObject to do the same thing with a little more effort. The harder paths are better if the JSON is really "weird" and requires special effort to get into sensible C# objects.
This isn't quite bad enough to need to use JArray. Obviously you can't make a C# object with a property named "1", "2", "3", and so on, but there's another way to go about this. Any JSON object is effectively a Dictionary<string, object>, so our first decision can be that this is our outer object.
The inner objects of this dictionary do have a well-defined type. They have four properties that are strings, though maybe for your logic "id" will be a number. So we can make an object to represent this and have a more specific Dictionary.
So I'd start with:
public class JsonTask
{
public string Id { get; set; }
public string Entrant { get; set; }
public string Recipient { get; set; }
public string Task { get; set; }
}
Then the code to get the dictionary is:
var dict = JsonConvert.DeserializeObject<Dictionary<string, JsonTask>>(json);
From there, getting an array could be:
var asArray = dict.Values.ToArray();
If order is super important, you might have to do something more complex. If you know all the properties are always sequential integers, a for loop over Keys is good enough. If they might not be ordered, you might try converting Keys to an array, sorting it, then using each key to fetch each value.
I don't think the other comment about deserializing to a list will work, generally you can only deserialize JSON arrays to lists, and this is more of an object being used as a dictionary.
That... is not an array, is it? An array is using [], you just have an object with properties 1, 2, and 3. I don't think that'd even work.
To deserialize into a list, you'd do something like JsonConvert.DeserializeObject<List<Details>>(webResult1);
You can use json2csharp.com to Convert your json to object model
- Go to json2csharp.com
- Past your JSON in the Box.
- Clik on Generate.
- You will get C# Code for your object model
- Deserialize by
var model = JsonConvert.DeserializeObject<RootObject>(json);using NewtonJson
Here, It will generate something like this:
public class MatrixModel
{
public class Option
{
public string text { get; set; }
public string selectedMarks { get; set; }
}
public class Model
{
public List<Option> options { get; set; }
public int maxOptions { get; set; }
public int minOptions { get; set; }
public bool isAnswerRequired { get; set; }
public string selectedOption { get; set; }
public string answerText { get; set; }
public bool isRangeType { get; set; }
public string from { get; set; }
public string to { get; set; }
public string mins { get; set; }
public string secs { get; set; }
}
public class Question
{
public int QuestionId { get; set; }
public string QuestionText { get; set; }
public int TypeId { get; set; }
public string TypeName { get; set; }
public Model Model { get; set; }
}
public class RootObject
{
public Question Question { get; set; }
public string CheckType { get; set; }
public string S1 { get; set; }
public string S2 { get; set; }
public string S3 { get; set; }
public string S4 { get; set; }
public string S5 { get; set; }
public string S6 { get; set; }
public string S7 { get; set; }
public string S8 { get; set; }
public string S9 { get; set; }
public string S10 { get; set; }
public string ScoreIfNoMatch { get; set; }
}
}
Then you can deserialize as:
var model = JsonConvert.DeserializeObject<List<MatrixModel.RootObject>>(json);
public static class Helper
{
public static string AsJsonList<T>(List<T> tt)
{
return new JavaScriptSerializer().Serialize(tt);
}
public static string AsJson<T>(T t)
{
return new JavaScriptSerializer().Serialize(t);
}
public static List<T> AsObjectList<T>(string tt)
{
return new JavaScriptSerializer().Deserialize<List<T>>(tt);
}
public static T AsObject<T>(string t)
{
return new JavaScriptSerializer().Deserialize<T>(t);
}
}
If you don't want to create a class :
You can use JObject.Parse() method for deserializing dynamically.
As @SirRufo said, you can deserialize a JSON array into a list. but your JSON string in the sample is a single object!
Anyway, you deserialize JSON string to object with the use JSON.Net.
First, you have a class for Deserialize :
public class Data
{
public string name { get; set; }
public string Fname { get; set; }
public string S1 { get; set; }
public string S2 { get; set; }
public string S3 { get; set; }
}
Then you can deserialize JSON string to C# class :
var obj = JsonConvert.DeserializeObject<Data>(jsonString);
If your array continues with X4,Y4,Z4, you have a problem since, for deserializing the strong type class from the JSON, the array entries should be known. To deserialize the current JSON, use the following classes:
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string X1 { get; set; }
public string Y1 { get; set; }
public string Z1 { get; set; }
public string X2 { get; set; }
public string Y2 { get; set; }
public string Z2 { get; set; }
public string X3 { get; set; }
public string Y3 { get; set; }
public string Z3 { get; set; }
}
You may read the JSON dynamically instead of deserializing the array:
using System.Text.Json.Nodes;
var jsonString = "[{\"X1\":\"x1\",\"Y1\":\"y1\",\"Z1\":\"z1\"},{\"X2\":\"x2\",\"Y2\":\"y2\",\"Z2\":\"z2\"},{\"X3\":\"x3\",\"Y3\":\"y3\",\"Z3\":\"z3\"}]";
var jsonObject = JsonNode.Parse(jsonString);
Console.WriteLine(jsonObject.ToString());
Console.WriteLine(jsonObject[0]["X1"]);
Alon.
Hi @Julio Bello ,
[{"X1":"x1","Y1":"y1","Z1":"z1"},{"X2":"x2","Y2":"y2","Z2":"z2"},{"X3":"x3","Y3":"y3","Z3":"z3"},...]
From the above JSON string, we can see that each property (key-value pair, such as "X1":"x1", "X2":"x2") has a different property name or key value, in this scenario the property is not fixed so we can directly use it as the class's property.
So, for the above JSON string, I suggest you could deserialize it uses a Dictionary, you can refer to the following sample code:
//required using System.Text.Json;
var values = new List>()
{
new Dictionary()
{
{"X1", "x1"},{"Y1", "Y1"},{"Z1", "Z1"}
},
new Dictionary()
{
{"X2", "x2"},{"Y2", "Y2"},{"Z2", "Z2"}
}
};
var jsonstring = JsonSerializer.Serialize(values);
//jsonstring: [{"X1":"x1","Y1":"Y1","Z1":"Z1"},{"X2":"x2","Y2":"Y2","Z2":"Z2"}]
var reult1 = JsonSerializer.Deserialize>>(jsonstring);
var test = new TestModel()
{
Item = new List>()
{
new Dictionary()
{
{"X1", "x1"},{"Y1", "Y1"},{"Z1", "Z1"}
},
new Dictionary()
{
{"X2", "x2"},{"Y2", "Y2"},{"Z2", "Z2"}
}
}
};
var jsonstring2 = JsonSerializer.Serialize(test);
//josnstring2: {"Item":[{"X1":"x1","Y1":"Y1","Z1":"Z1"},{"X2":"x2","Y2":"Y2","Z2":"Z2"}]}
var result2 = JsonSerializer.Deserialize(jsonstring2);
The TestModel
public class TestModel
{
public List> Item { get; set; }
}
The output is like this:
And this sample code:
var jsonstr = "[{\"X1\":\"x1\",\"Y1\":\"Y1\",\"Z1\":\"Z1\"},{\"X2\":\"x2\",\"Y2\":\"Y2\",\"Z2\":\"Z2\"}]";
var result3 = JsonSerializer.Deserialize>>(jsonstr);
The result:
After that you can find the data from the Dictionary. More detailed information about Dictionary, see Dictionary Class
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion
You need to explicitly convert the type, ie
return Json.Decode<ShoppingCart>(value);
Similar question has been asked earlier, Using Newtonsoft JsonConvert.DeserializeObject works well for the purpose, check the following links. You may even consider Javascriptserializer
How to convert Json array to list of objects in c#
Deserialize JSON array(or list) in C#
deserialize json array list in c#