I get this string on my controller:
"[{\"id\":12},{\"id\":2,\"children\":[{\"id\":3},{\"id\":4}]}]"
I want to parse this, and create one foreach inside other foreach to get the parents and children.
I've been trying this:
var object = JsonConvert.DeserializeObject<MenuJson>(json);
where MenuJson is:
public class MenuJson
{
[JsonProperty("id")]
public string id { get; set; }
[JsonProperty("children")]
public List<string> children { get; set; }
}
I got this erro:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'AIO.Controllers.AdminMenuController+MenuJson' 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 '', line 1, position 1.
And I tried other approach:
var objects = JsonConvert.DeserializeObject<JObject>(json);
foreach (var property in objects)
{
var id = property.Value;
foreach (var innerProperty in ((JObject)property.Value).Properties())
{
var child = property.Value;
}
}
Both I got errors when I try to convert the string.
My question is, How can I make this working?
And for my string, which approach is the best for my needs?
Have you tried this?
public class MenuJson
{
[JsonProperty("id")]
public string id { get; set; }
[JsonProperty("children")]
public List<MenuJson> children { get; set; }
}
var list = JsonConvert.DeserializeObject<List<MenuJson>>(json);
Here's an working example:
public void Test()
{
string json = "[{\"id\":12},{\"id\":2,\"children\":[{\"id\":3},{\"id\":4}]}]";
var objects = JsonConvert.DeserializeObject<List<MenuJson>>(json);
foreach (var property in objects)
{
var id = property.id;
foreach (var child in property.children)
{
//child
}
}
}
Related
I am getting JSON string request from the server side. That part not handling by my self. They send the request as following (policyJson)
{"Data":"[{\"NAME\":\"BOARD OF INVESTMENT OF SRI LANKA\",\"STARTDATE\":\"\\\/Date(1584210600000)\\\/\",\"ENDDATE\":\"\\\/Date(1615660200000)\\\/\",\"SCOPE\":\"As per the standard SLIC \\\"Medical Expenses\\\" Policy Wordings\",\"DEBITCODENO\":1274}]","ID":200}
Then I Deserialize using
BV_response _res_pol = JsonConvert.DeserializeObject<BV_response>(policyJson);
Class BV_response
public class BV_response
{
public int ID { get; set; }
public string Data { get; set; }
}
Then
string res = _res_pol.Data.Replace("\\", "");
var policyDetails = JsonConvert.DeserializeObject<PolicyData>(res);
Class PolicyData
public class PolicyData
{
public string NAME { get; set; }
public DateTime STARTDATE { get; set; }
public DateTime ENDDATE { get; set; }
public string SCOPE { get; set; }
public int DEBITCODENO { get; set; }
}
For this JSON string I am getting following exception in this line
var policyDetails = JsonConvert.DeserializeObject(res);
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'SHE_AppWS.Models.PolicyData' 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<T> 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 '', line 1, position 1.
This is valid JSON, and does not need string manipulation. It's just JSON stored within JSON.
Do not try unescaping JSON yourself. If the JSON is not valid, get it fixed at source.
Your problem is that you are deserializing the inner JSON to a single object, but it is an array.
Instead, deserialize to a List<> or array.
BV_response _res_pol = JsonConvert.DeserializeObject<BV_response>(policyJson);
var policyDetails = JsonConvert.DeserializeObject<List<PolicyData>>(_res_pol.Data);
I am trying to serialize a object defined below. This happens correctly using Newtonsoft JsonConvert. This returns a string.
When i try to deserialize the string back into the defined object it doesn't work and throws exception
private class PlotSetFeatureStateInfo
{
public IDictionary<int,IDictionary<AxisTypeAndUnitInfo,ManualScaleInfo>> PersistentScaleInfo
{
get;
set;
}
public IDictionary<Guid,ScaleType> PlotIdVsLocalScaleType { get; set; }
public IDictionary<Guid,IDictionary<AxisTypeAndUnitInfo,
PlotScales.PersistentScaleData>> PlotIdVsPersistentScaleData { get; set;}
}
var foo = new FeatureStateInfo
{
//Fill values
};
var res = JsonConvert.SerializeObject(foo);
var deserializedProperty = JsonConvert.DeserializeObject<FeatureStateInfo>(res);//Throws error
Getting the below error
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'System.Collections.Generic.IDictionary2[System.Int32,System.Collections.Generic.IDictionary2[Axis,ManualScale]]'
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
Posting the sample JSON without any edits. This is a valid json.
{"PersistentScaleInfo":[{"Key":1,"Value":[{"Key":{"AxisType":0,"UnitInfo":{"UnitId":"601988e7-06a1-4dfd-9bba-535989b3afba","SubunitId":"00000000-0000-0000-0000-000000000000"}},"Value":{"Units":"Hz ","MaxScale":400,"MinScale":0.062,"IsAuto":false,"Axes":"X","AxisType":0,"UnitInfo":{"UnitId":"601988e7-06a1-4dfd-9bba-535989b3afba","SubunitId":"00000000-0000-0000-0000-000000000000"},"IsMinLessThanMax":true}},{"Key":{"AxisType":1,"UnitInfo":{"UnitId":"250f1aea-b8e3-4a4d-98e0-f60abded10a4","SubunitId":"94d2baf0-3bc0-41f7-b207-d8ce54e65e35"}},"Value":{"Units":"in/s rms","MaxScale":0.015,"MinScale":0,"IsAuto":false,"Axes":"Y","AxisType":1,"UnitInfo":{"UnitId":"250f1aea-b8e3-4a4d-98e0-f60abded10a4","SubunitId":"94d2baf0-3bc0-41f7-b207-d8ce54e65e35"},"IsMinLessThanMax":true}}]}],"PlotIdVsLocalScaleType":[{"Key":"5ef394a9-98ad-4f52-b916-b698ae4ef351","Value":2}],"PlotIdVsPersistentScaleData":[{"Key":"5ef394a9-98ad-4f52-b916-b698ae4ef351","Value":[{"Key":{"AxisType":0,"UnitInfo":{"UnitId":"601988e7-06a1-4dfd-9bba-535989b3afba","SubunitId":"00000000-0000-0000-0000-000000000000"}},"Value":{"ManualScaleRange":{"MaxScale":400,"MinScale":0.062},"IsVisibleOnView":true,"IsAutoChecked":false,"AreManualScalesSet":true}},{"Key":{"AxisType":1,"UnitInfo":{"UnitId":"250f1aea-b8e3-4a4d-98e0-f60abded10a4","SubunitId":"94d2baf0-3bc0-41f7-b207-d8ce54e65e35"}},"Value":{"ManualScaleRange":{"MaxScale":0.015,"MinScale":0},"IsVisibleOnView":true,"IsAutoChecked":false,"AreManualScalesSet":true}}]}]}
SOLUTION:
i modified the class according to everyones suggestion as below.
This works fine for me
public class PlotSetFeatureStateInfo
{
public List<KeyValuePair<int, List<KeyValuePair<AxisTypeAndUnitInfo, ManualScaleInfo>>>> PersistentScaleInfo
{
get;
set;
}
public List<KeyValuePair<Guid, ScaleType>>PlotIdVsLocalScaleType { get; set; }
public List<KeyValuePair<Guid,List<KeyValuePair<AxisTypeAndUnitInfo,
PlotScales.PersistentScaleData>>>> PlotIdVsPersistentScaleData { get; set; }
}
Thank you :)
Below is a Json :
[{
"Result": {
"description": "Application Security Supp Specialist",
"code": "40000003"
}
}, {
"Result": {
"description": "Gvt Cyber Intelligence Specialist",
"code": "40001416"
}
}, {
"Result": {
"description": "Gvt Record Retention Specialist",
"code": "40001428"
}
}]
And below is the class structure which i have created as i need to fill this into a C# object.
I am trying to create a collection of RulesEngineOutput and fill it with the json contents.
public class RulesEngineOutput
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
}
public class RulesEngineOutputCollection
{
public IEnumerable<RulesEngineOutput> ProbableRoles { get; set; }
}
I am trying to achieve this using below code :
var bodyJson = JsonConvert.SerializeObject(bodyString);
RulesEngineOutputCollection result = new RulesEngineOutputCollection();
foreach (var item in bodyJson)
{
result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(item.ToString());
}
But this is throwing exception as the item gets a char, what i am thinkiong is that i need to pass a JSON object in the loop but i am not able to get one.
Everytime i get is a JSON string.
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'RulesEngineOutputCollection' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo 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.
The problem is that you have an intermediary object between your RulesEngineOutput and your collection. You need to restructure your objects as such:
public class RulesEngineOutput
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
}
public class RulesEngineOutputResult
{
public RulesEngineOutput Result { get; set; }
}
public class RulesEngineOutputCollection
{
public IEnumerable<RulesEngineOutputResult> ProbableRoles { get; set; }
}
And then when you have this restructuring done, you can deserialize directly to your RulesEngineOutputCollection instead of to an object and iterating and deserializing again.
result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(bodyString);
Thanks a lot Max,Nathan and others. So finally i made some changes in code and below is the code which i changed tomake the things work :
var jToken = JObject.Parse(responseContent);
var bodyString = jToken.SelectToken("body");
var bodyJson = JsonConvert.SerializeObject(bodyString);
List<RulesEngineOutput> result = new List<RulesEngineOutput>();
try
{
foreach (var item in bodyString)
{
var formattedItem = item.SelectToken("Result");
var resultItem = JsonConvert.DeserializeObject<RulesEngineOutput>(formattedItem.ToString());
result.Add(resultItem);
}
}
Hope it helps others as well.
As Nathan Werry said, you have an object layered into another object and because of that, you cannot deserialize the data in the way you want it. However, you can work around that if you first create an array of these results and assign it later to your ProbableRoles property:
var rules = new RulesEngineOutputCollection
{
ProbableRoles = JsonConvert.DeserializeObject<Result[]>(bodyString).Select(r => r.Data).ToList()
};
public class Result
{
[JsonProperty("Result")]
public RulesEngineOutput Data { get; set; }
}
Everything else stays the same. You basically create a new list out of your array of results. I could also assign the Select() result directly (without calling .ToList()) but this ensures that the object actually has the data and not just a reference to an enumeration.
this is the json file:
{
"Message": {
"Code": 200,
"Message": "request success"
},
"Data": {
"USD": {
"Jual": "13780",
"Beli": "13760"
}
},
"LastUpdate": "2015-11-27 22:00:11",
"ProcessingTime": 0.0794281959534
}
I have a problem when I am converting to class like this:
public class Message
{
public int Code { get; set; }
public string Message { get; set; }
}
public class USD
{
public string Jual { get; set; }
public string Beli { get; set; }
}
public class Data
{
public USD USD { get; set; }
}
public class RootObject
{
public Message Message { get; set; }
public Data Data { get; set; }
public string LastUpdate { get; set; }
public double ProcessingTime { get; set; }
}
and when I deserialized with this code :
private void button1_Click(object sender, EventArgs e)
{
WebClient wc = new WebClient();
var json = wc.DownloadString(textBox1.Text);
List<User> users = JsonConvert.DeserializeObject<List<User>>(json);
dataGridView1.DataSource = json;
}
When I run the code I get an unhandled exception which says:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[WindowsFormApp.EmployeeInfo+Areas]' 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<T>) 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.”
Can anyone tell me what I am doing wrong and how to get the last item deserialized correctly?
JSON.Net is expecting (when you pass a collection type to the DeserializeObject method), that the root object is an array. According to your data, it's an object and needs to be processed as a singular user.
And then you need to pass that to the dataSource, so you'd then wrap the deserialized User into var userList = new List<User>{user};
The error message is pretty straightforward. You are trying to deserialize something that isn't an array (your JSON string) into a collection (List<User>). It's not a collection so you can't do that. You should be doing something like JsonConvert.DeserializeObject<RootObject>(json) to get a single object.
I have a Json like this :
[{"id":"54718","title":"Khaleda to visit China","corres":"Special Correspondent","details":"DHAKA: On a 7-day visit, opposition BNP Chairperson Khaleda Zia will leave Dhaka for China on October 14.","photo":"2012October\/SM\/Khaleda-new-sm20121003132805.jpg"}]
To parse this Json , so far I have done :
public class Attributes
{
[JsonProperty("id")]
public string ID{ get; set; }
[JsonProperty("title")]
public string TITLE { get; set; }
[JsonProperty("corres")]
public string CORRES { get; set; }
[JsonProperty("details")]
public string DETAIL { get; set; }
[JsonProperty("photo")]
public string LINK { get; set; }
}
public class DataJsonAttributeContainer
{
public List<Attributes> NewsList{ get; set; }
//public Attributes attributes { get; set; }
}
public static T DeserializeFromJson<T>(string json)
{ //I'm getting the error here
T deserializedProduct = JsonConvert.DeserializeObject<T>(json);
return deserializedProduct;
}
& In my code :
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//parse data
var container = DeserializeFromJson<DataJsonAttributeContainer>(e.Result);
//load into list
for (i = 0; i < container.NewsList.Count ; i++)
{
newData[i] = new data();
newData[i].id = container.NewsList[i].ID;
newData[i].title = container.NewsList[i].TITLE;
newData[i].price = container.NewsList[i].CORRES;
newData[i].image = container.NewsList[i].DETAIL;
newData[i].link = container.NewsList[i].LINK;
}
The Problem is : container is getting the json from web server which I can see at debugger , but it's shoeing an exception while deserializing . Can anybody help please ?
The Exception I'm getting :
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'BanglaNewsPivot.MainPage+DataJsonAttributeContainer' 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<T> 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 '', line 1, position 1.
Your json is an array (not a single object containing array). Calling your DeserializeFromJson as below
var attrs = DeserializeFromJson<List<Attributes>>(e.Result);
is enough.
--EDIT--
foreach (var attr in attrs)
{
Console.WriteLine("{0} {1}", attr.ID, attr.TITLE);
}