The idea is that I want to take my string, convert it to a JSON object, then loop through the results array to extract all of the id fields and put them in a separate array.
I've tried multiple 'C# string to JSON examples' but have gotten the farthest with this particular bit of code.
main:
String myString = "{
"total": 111,
"token": "abcdefghijklmn",
"results": [
{
"id": "001",
"some_stuff": {
"aValue": 0,
"bValue": 1
}
},
{
"id": "001",
"some_stuff": {
"aValue": 0,
"bValue": 1
}
},
{
"id": "001",
"some_stuff": {
"aValue": 0,
"bValue": 1
}
},
],
"whatdidido": {
"iretrieved": "yes"
}
}";
var list = JsonConvert.DeserializeObject<List<IdReturn>>(myString);
classes:
public class IdReturn
{
public int total { get; set; }
public string token { get; set; }
public List<Attribute> results { get; set; }
}
public class results
{
public string id { get; set; }
public string some_stuff { get; set; }
}
The expected result is a JSON object that I can use as: list.results[i].id to get to each id. The error message that I get from the code above is:
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[myExample.IdReturn]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
First your string is not written as valid C#, it should be:
String myString = #"{
""total"": 111,
""token"": ""abcdefghijklmn"",
""results"": [
{
""id"": ""001"",
""some_stuff"": {
""aValue"": 0,
""bValue"": 1
}
},
{
""id"": ""001"",
""some_stuff"": {
""aValue"": 0,
""bValue"": 1
}
},
{
""id"": ""001"",
""some_stuff"": {
""aValue"": 0,
""bValue"": 1
}
},
],
""whatdidido"": {
""iretrieved"": ""yes""
}
}";
Next you need a set of classes to represent the JSON structure:
public class Rootobject
{
public int total { get; set; }
public string token { get; set; }
public Result[] results { get; set; }
public Whatdidido whatdidido { get; set; }
}
public class Whatdidido
{
public string iretrieved { get; set; }
}
public class Result
{
public string id { get; set; }
public Some_Stuff some_stuff { get; set; }
}
public class Some_Stuff
{
public int aValue { get; set; }
public int bValue { get; set; }
}
And finally to deserialize it and print each id you can do this:
var root = JsonConvert.DeserializeObject<Rootobject>(myString);
Console.WriteLine(string.Join(",", root.results.Select(item => item.id)));
Which, for your sample will result in:
001,001,001
Related
I have little to no experience in JSON and I am stuck with a problem. Any help is appreciated.
I want to access specifically the names' values from the additionalInformation array.
JSON Response:
{
"statusCode": 200,
"version": 1,
"jsonData": [
{
"additionalInformation": [
{
"id": "XXX94XXXX9xxXx_xxxXXXX",
"name": "xxxx xxx x xxxxxxxx"
},
{
"id": "0xXXxcXxv5PQqT$6i2zLgV",
"name": "xxx xxxxxxxx"
},
{
"id": "11Krt_our2rPCPqJ_2fKZR",
"name": "xxx xxxxxxxx xx"
},
{
"id": "2jYw4IyBP8KuozM_ej7DGf",
"name": "xxxxxxx 1"
},
{
"id": "3B8O805wL1ufabHMz1Je3v",
"name": "xxxxxxx 2"
},
{
"id": "0FVKUYZkvFaxd_OQUiyPBZ",
"name": "xxxxxxx"
},
{
"id": "3O41QFd0573QQvFco5zUUP",
"name": "Xxxxxxxxx"
}
],
"type": 0
}
],
"errorMessages": [],
"warningMessages": [],
"informationMessages": []
}
Model:
public class CFunctions
{
public int statusCode { get; set; }
public int version { get; set; }
public List<PFunctions>[] jsonData { get; set; }
public List<string> errorMessages { get; set; }
public List<string> warningMessages { get; set; }
public List<string> informationMessages { get; set; }
/*public CFunctions()
{
jsonData = new List<PFunctions>();
}*/
}
[Serializable]
public class PFunctions
{
public List<PAdditionalInfo>[] additionalInformation { get; set; }
public int type { get; set; }
/*public PFunctions()
{
additionalInformation = new List<PAdditionalInfo>();
}*/
}
[Serializable]
public class PAdditionalInfo
{
public Guid id { get; set; }
public string name { get; set; }
}
Deserialisation
var request = UnityWebRequest.Get(baseurl);
var operation = request.SendWebRequest();
var jsonResponse = request.downloadHandler.text;
List<CFunctions>[] PFunctionsList = JsonConvert.DeserializeObject<List<CFunctions>[]>(jsonResponse);
Error:
Cannot deserialize the current JSON object into type 'System.Collections.Generic.List`1[CFunctions][]' because the type requires a JSON array to deserialize correctly.
To fix this error either change the JSON to a JSON array or change the deserialized type so that it is a normal .NET type that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'statusCode', line 1, position 14.
UnityEngine.Debug:Log(Object)
What I tried
The error pertains even when I changed List<PAdditionalInfo> to List<PAdditionalInfo>[]
I am not sure how to use JsonObjectAttribute and if it is the best way.
You've declared an array of List<T> in the models, eg List<PAdditionalInfo>[]. The json represents single arrays, not nested. You can fix that by choosing one or the other (I decided to use List<> but array is valid too):
public class PFunctions
{
public List<PAdditionalInfo> additionalInformation { get; set; } // removed []
...
}
public class CFunctions
{
public int statusCode { get; set; }
public int version { get; set; }
public List<PFunctions> jsonData { get; set; } // removed []
...
}
The class you're deserializing to is incorrect. Deserialize to the correct type (which is CFunctions not List<CFunctions>[]):
CFunctions cFunctions = JsonConvert.DeserializeObject<CFunctions>(json);
the most efficient way to get an additional information is this one line code and you only need one class
List<AdditionalInformation> additionalInformation = JObject.Parse(json)
["jsonData"][0]["additionalInformation"].ToObject<List<AdditionalInformation>>();
class
public class AdditionalInformation
{
public string id { get; set; }
public string name { get; set; }
}
My problem is that I'm getting this error when I try to deserialize my API json response.
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Entities.JsonDataType]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
My json data return something like this
{
"success": true,
"result": [
{
"name": "USD Amerikan Doları",
"buying": "6.6920",
"selling": "6.6995"
},
{
"name": "EUR Euro",
"buying": "7.7322",
"selling": "7.7393"
},
{
"name": "GBP İngiliz Sterlini",
"buying": "8.5933",
"selling": "8.6041"
},
"..."
]
}
My class properties:
public class JsonDataType
{
//public string name { get; set; }
//public string buying { get; set; }
//public string selling { get; set; }
public bool success { get; set; }
public List<Result> result { get; set; }
}
public class Result
{
public string name { get; set; }
public string buying { get; set; }
public string selling { get; set; }
}
And I'm getting the error when I deserialize:
List<JsonDataType> X = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JsonDataType>>(response.Content);
Also I tried these codes but none of them working
JsonDataType X = JsonConvert.DeserializeObject(response.Content);
IEnumerable<Result> X = (JsonDataType)JsonConvert.DeserializeObject<IEnumerable<Result>>(response.Content, typeof(JsonDataType));
List<Result> X = JsonConvert.DeserializeObject<JsonDataType>(response.Content, typeof(Result));
If someone could help me i will be so peaceful.
Thanks for your time in advance (✿◠‿◠)
Here is my answer
JsonDataType X = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonDataType>(response.Content);
I have the following JSON format delivered by a third party:
{
"data": {
"objects": {
"0ea73fa9333a7cbeb2d8c69a14b9970f": {
"Id": "0ea73fa9333a7cbeb2d8c69a14b9970f",
"Name": "test"
},
"38b1390ff6bc8a9837105d181000bcc8": {
"Id": "38b1390ff6bc8a9837105d181000bcc8",
"Name": "test"
}
}
}}
which i'm deserializing using this model:
public class ObjectTypes
{
public ObjectTypeList data { get; set; }
public class ObjectTypeList
{
public Dictionary<string, Object> objects { get; set; }
}
public class Object
{
public string Id { get; set; }
public string Name { get; set; }
}
}
This works fine, however sometimes the JSON is empty like this:
{
"data": {
"objects": []
}
}
Which results in this exception:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,Models.ObjectTypes+Object]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'data.objects', line 1, position 20.
Any suggestions on how to resolve this?
You shoul deserialize on the type ObjectTypes
public partial class ObjectTypes
{
[JsonProperty("data")]
public Data Data { get; set; }
}
public partial class Data
{
[JsonProperty("objects")]
public Dictionary<string, Object> Objects { get; set; }
}
public partial class Object
{
[JsonProperty("Id")]
public string Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
As I already mentioned in my comment, json structure doesn't match in both strings. objects can be either an object (Dictionary) or an array.
I have created a small parser class that will parse the json and check if objects is an object (Dictionary) or an array. In the first case it will return an empty ObjectTypes object but in the second case it will deserialize the json string into an ObjectTypes object.
public class ObjectTypesParser
{
public ObjectTypes Parse(string json)
{
JToken token = JToken.Parse(json);
var objectsToken = token.First.First.First.FirstOrDefault();
if (objectsToken is JArray)
{
/*
Special case - json with an empty array:
{
""data"": {
""objects"": []
}
}
*/
return new ObjectTypes();
}
// json containing a dictionary:
ObjectTypes data = JsonConvert.DeserializeObject<ObjectTypes>(json);
return data;
}
}
C# classes:
public class ObjectTypes
{
[JsonProperty("data")]
public ObjectTypeList Data { get; set; }
public ObjectTypes()
{
Data = new ObjectTypeList();
}
}
public class ObjectTypeList
{
[JsonProperty("objects")]
public Dictionary<string, ObjectData> Objects { get; set; }
public ObjectTypeList()
{
Objects = new Dictionary<string, ObjectData>();
}
}
public class ObjectData
{
[JsonProperty("Id")]
public string Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
Using the code:
string json1 = #"{
""data"": {
""objects"": {
""0ea73fa9333a7cbeb2d8c69a14b9970f"": {
""Id"": ""0ea73fa9333a7cbeb2d8c69a14b9970f"",
""Name"": ""test""
},
""38b1390ff6bc8a9837105d181000bcc8"": {
""Id"": ""38b1390ff6bc8a9837105d181000bcc8"",
""Name"": ""test""
}
}
}}";
string json2 = #"{
""data"": {
""objects"": []
}
}";
var parser = new ObjectTypesParser();
ObjectTypes data1 = parser.Parse(json1);
ObjectTypes data2 = parser.Parse(json2);
My JSON feed has nested objects like this:
{
"id": 1765116,
"name": "StrozeR",
"birth": "2009-08-12",
"avatar": "http:\/\/static.erepublik.com\/uploads\/avatars\/Citizens\/2009\/08\/12\/f19db99e9baddad73981d214a6e576ef_100x100.jpg",
"online": true,
"alive": true,
"ban": null,
"level": 61,
"experience": 183920,
"strength": 25779.42,
"rank": {
"points": 133687587,
"level": 63,
"image": "http:\/\/www.erepublik.com\/images\/modules\/ranks\/god_of_war_1.png",
"name": "God of War*"
},
"elite_citizen": false,
"national_rank": 6,
"residence": {
"country": {
"id": 81,
"name": "Republic of China (Taiwan)",
"code": "TW"
},
"region": {
"id": 484,
"name": "Hokkaido"
}
}
}
and my object classes are like this:
class Citizen
{
public class Rank
{
public int points { get; set; }
public int level { get; set; }
public string image { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public string avatar { get; set; }
public bool online { get; set; }
public bool alive { get; set; }
public string ban { get; set; }
public string birth { get; set; }
public int level { get; set; }
public int experience { get; set; }
public double strength { get; set; }
public List<Rank> rank { get; set; }
}
}
I try to parse my JSON data with following code
private async void getJSON()
{
var http = new HttpClient();
http.MaxResponseContentBufferSize = Int32.MaxValue;
var response = await http.GetStringAsync(uri);
var rootObject = JsonConvert.DeserializeObject<Citizen.RootObject>(response);
uriTB.Text = rootObject.name;
responseDebug.Text = response;
}
but I get the following error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Erepublik.Citizen+Rank]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I can't even parse the value in the main object. Anyway to fix this? and how can I parse a value inside of a nested object? for example: "points" in "rank"
Like the error message says, your rank property in the .NET class is a List<Rank>, but in your JSON it's just a nested object, not an array. Change it to just a Rank instead of a List<Rank>.
Arrays in JSON (or any Javascript, really) are enclosed in []. The {} characters specify a single object. The CLR type has to roughly match the JSON type in order to deserialize. Object to object, array to array.
static void Main(string[] args)
{
var json = #"{ ""rows"": [
[
{
""colspan"": 4,
""id"": ""ContentPanel1""
},
{
""colspan"": 8,
""id"": ""ContentPanel2""
}
],
[
{
""colspan"": 12,
""id"": ""ContentPanel3""
}
]
]}";
var json_serializer = new JavaScriptSerializer();
var jsonData = json_serializer.Deserialize<Grid>(json);
Console.ReadKey();
}
[Serializable]
public class Grid
{
public List<Row> rows { get; set; }
}
[Serializable]
public class Row
{
public int colspan { get; set; }
public int id { get; set; }
public List<Row> rows { get; set; }
}
I am trying to convert this JSON string to a C# object, but I am finding it hard because the error message is not very intuitive. Any JSON punters please help!
ERROR Type 'ConsoleApplication1.Program+Row' is not supported for deserialization of an array.
First we get:
Type 'Row' is not supported for deserialization of an array.
The JSON with [ [ shows a nested array. So either change the JSON, or make rows a Row[][]:
public Row[][] rows { get; set; }
Now we get:
ContentPanel1 is not a valid value for Int32.
well...
public int id { get; set; }
vs
""id"": ""ContentPanel1""
Now: "ContentPanel1" is not an int. Make id a string:
public string id { get; set; }