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.
Related
Here is the JSON response
{
"result": [
{
"sys_id": "85071a1347c12200e0ef563dbb9a71c1",
"number": "INC0020001",
"description": ""
}
]
}
Here is my JSON class
public class Result
{
public string sys_id { get; set; }
public string number { get; set; }
public string description { get; set; }
}
public class jsonResult
{
public IList<Result> result { get; set; }
}
Here is what I am doing to deserialize
strReponse = rClient.makeReqest();
Result deserializedProduct = JsonConvert.DeserializeObject<Result>(strReponse);
System.Windows.Forms.MessageBox.Show(deserializedProduct.number);
It looks like it never assigns anything into my JSON class.
This is my first time dealing with JSON and Web calls. What am i missing? The API call does return the correct JSON, and I used json2csharp to make my json class.
Thank you!
You need deserialize full object represented in json string. Which is jsonResult in your case.
After, you will get access to values, you need, through properties of jsonResult
strReponse = rClient.makeReqest();
var deserializedResult = JsonConvert.DeserializeObject<jsonResult>(strReponse);
var number = deserializedResult.result.First().number;
MessageBox.Show(number);
Because jsonResult.result is of type IList will be safer to loop through all possible results
strReponse = rClient.makeReqest();
var deserializedResult = JsonConvert.DeserializeObject<jsonResult>(strReponse);
foreach (var result in deserializedResult.result)
{
MessageBox.Show(result.number);
}
You should deserialize to jsonResult NOT Result.
So try this :
jsonResult deserializedProduct = JsonConvert.DeserializeObject<jsonResult>(strReponse);
Also you may get values of the list like this:
var firstResult = deserializedProduct.result.FirstOrDefault();
var someSpecialResults = deserializedProduct.result.Where(r=>r.number.Contains("123"));
Also :
if (firstResult != null)
System.Windows.Forms.MessageBox.Show(firstResult .number);
Also you may iterate them like this :
deserializedProduct.result.ForEach(r=> System.Windows.Forms.MessageBox.Show(r.number);)
I hope to be helpful for you:)
Thanks in advance for your help.
I have a JSON file that contains a list of nested objects. Using the code below - I get an exception on the call to DeserializeObject. We are using JSON.net
Any help is appreciated
JSON:
[
{
"Email": "james#example.com",
"Active": true,
"CreatedDate": "2013-01-20T00:00:00Z",
"Input": {
"User": "Jim",
"Admin": "John"
},
"Output": {
"Version": "12345",
"Nylon": "None"
}
},
{
"Email": "bob#example.com",
"Active": true,
"CreatedDate": "2013-01-21T00:00:00Z",
"Input": {
"User": "Bob",
"Admin": "John"
},
"Output": {
"Version": "12399",
"Nylon": "134"
}
}
]
To support the deserialization I have created the following class structure.
public class Test002
{
public class Input
{
public string User { get; set; }
public string Admin { get; set; }
}
public class Output
{
public string Version { get; set; }
public string Nylon { get; set; }
}
public class RootObject
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public Input input { get; set; }
public Output output { get; set; }
}
public class TestCases
{
public List<RootObject> rootObjects { get; set; }
}
}
And finally here is the call to JSON.net JsonConvert.DeserializeObject - throws the following exception.
Test002.TestCases tTestCases = JsonConvert.DeserializeObject<Test002.TestCases>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
I think I need something like this - to deseralize the list of objects - The code below fails
Test002.TestCases tTestCases = JsonConvert.DeserializeObject<IList<Test002.TestCases>>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
Exception:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'APISolution.Test002+TestCases' 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.
Why don't change TestCases to be a list? Works perfectly.
public class TestCases : List<RootObject> {}
The issue here is that you're trying to deserialize into an IList. IList is an interface, not a concrete type so JSON.NET doesn't know what to create. You need to tell it the exact type you want:
List<Test002.TestCases> tTestCases = JsonConvert.DeserializeObject<List<Test002.TestCases>>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
You could cast that into an IList like this:
IList<Test002.TestCases> tTestCases = JsonConvert.DeserializeObject<List<Test002.TestCases>>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
Perhaps try something as simple as this:
var tTestCases = JsonConvert.DeserializeObject<Test002.RootObject[]>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
According to the json-data specified, you got some IEnumerable of RootObjects.
Your classes are well-composed, except the Test002 class. Everything should be OK if you try to deserialize json-data as List. Try something like
var result = JsonConvert.DeserializeObject<List<RootObject>>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"));
If you strongly need the instance of your Test002 class, you should use
Test002.TestCases result = new TestCases(){
rootObjects = JsonConvert.DeserializeObject<List<RootObject>(File.ReadAllText(#"C:\test\Automation\API\Test002.json"))
};
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.
This is a JSON message I get from server (which I can't change). There might be many more objects (time / value) returned, but in this case there is only one. The format stays the same regardless.
{
"data": [
{
"time": "2014-12-12T13:52:43",
"value": 255.0
}
]
}
I'm trying to deserialize the JSON to a very simple C# object.
public class Dataentry {
public float Value { get; set; }
public DateTime Time { get; set; }
}
I've tried deserialization with Newtonsoft's JSON.Net and RestSharp libraries with no success. The following code doesn't work, but neither does anything else I've tried :-) I get no error -- just an empty object with default initial values.
var myObject = JsonConvert.DeserializeObject<Dataentry> (jsonString);
Since those libraries are not very intuitive or well documented in this kind of case, I'm lost. Is this kind of JSON impossible to deserialize? I really would like to use a ready-made library, so any help would be appreciated.
This is not working because your JSON is specifying a collection and you are trying to deseralize into one object. There are plenty of json to c# class generators you can paste json into to get an appropriate class definition(s) one such generator is located here
A more appropriate definition would be
public class Datum
{
public string time { get; set; }
public double value { get; set; }
}
public class RootObject
{
public List<Datum> data { get; set; }
}
Then deseralize as
var myObject = JsonConvert.DeserializeObject<RootObject> (jsonString);
I'd like add some extra explanetion to your question...
You write I'm trying to deserialize the JSON to a very simple C# object. - unfortunatelly this is not the complete truth. What you are trying is to deserialize a collection of a very simple C# objects. The indicator for this are the square brackets in your json:
{
"data": [
{
"time": "2014-12-12T13:52:43",
"value": 255.0
}
]
}
It means that there is a class with a property named data (it can ba mapped to some other name but for the sake of simplicity let's stick to this name) and that this property is a collection type. It can be one of any types that support the IEnumerable interface.
public class DataCollection
{
public DataItem[] data { get; set; }
//public List<DataItem> data { get; set; } // This would also work.
//public HashSet<DataItem> data { get; set; } // This would work too.
}
public class DataItem
{
public float value { get; set; }
public DateTime time { get; set; } // This would work because the time is in an ISO format I believe so json.net can parse it into DateTime.
}
The next step is to tell Json.Net how to deserialize it. Now when you know it's a complex data type you can use the type that describes the json structure for deserialization:
var dataCollection = JsonConvert.DeserializeObject<DataCollection>(jsonString);
If you didn't have the data property in you json string but something like this:
[
{
"time": "2014-12-12T13:52:43",
"value": 255.0
},
{
"time": "2016-12-12T13:52:43",
"value": 25.0
},
]
you could directly deserialize it as a collection:
var dataItems = JsonConvert.DeserializeObject<List<DataItem>>(jsonString);
or
var dataItems = JsonConvert.DeserializeObject<DataItem[]>(jsonString);
change your DateEntry binding Definition
public class ArrayData{
public DataEntry data {set; get;}
}
public class DataEntry {
public float Value { get; set; }
public DateTime Time { get; set; }
}
in your method now you can received an ArraData Object
be careful with datetime string values sent for correct binding
I am getting following JSON data
[{"id":"1","text":"System Admin","target":{"jQuery1710835279177001846":12},"checked":true,"state":"open"},
{"id":"2","text":"HRMS","target":{"jQuery1710835279177001846":34},"checked":false,"state":"open"},
{"id":"3","text":"SDBMS","target":{"jQuery1710835279177001846":42},"checked":false},
{"id":"8","text":"Admin","target":{"jQuery1710835279177001846":43},"checked":false},
{"id":"9","text":"My test Admin","target":{"jQuery1710835279177001846":44},"checked":false,"state":"open"},
{"id":"24","text":"ModuleName","target":{"jQuery1710835279177001846":46},"checked":false,"state":"open"}]
which try to parsed using Json.Net using strongly type
this are my property class
public class testclass
{
public string id { get; set; }
public string text { get; set; }
public string #checked { get; set; }
public string state { get; set; }
public target jQuery1710835279177001846 { get; set; }
}
public class testclass2
{
public List<testclass> testclass1 { get; set; }
}
public class target
{
public string jQuery1710835279177001846 { get; set; }
}
and here i am trying to access the data i am getting exception
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'QuexstERP.Web.UI.Areas.SysAdmin.Controllers.testclass' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
My controller code look like
public void Test(string Name, object modeldata)
{
var obj = JsonConvert.DeserializeObject<testclass>(Name);
}
Any idea how to solve this issue in C#
Your Json string looks to have serialized array object in it because it contains [ ]. It means you have a Json string which is formed after serialization of array object. So you need to deserialized into array object, so try this
var obj = JsonConvert.DeserializeObject<List<testclass>>(jsonString);
you have Array of TestClass. so it should be like this.
var model= JsonConvert.DeserializeObject<List<testclass>>(Name);
why you are using JSonConvert ? in MVC3 you can do like this
return Json(yourmodel,JsonRequestBehavior.AllowGet);
Your json objects are like this
{
"id":"1",
"text":"System Admin",
"target":{
"jQuery1710835279177001846":12
},
"checked":true,
"state":"open"
}
It should be like this I guess
{
"id":"1",
"text":"System Admin",
"jQuery1710835279177001846":12,
"checked":true,
"state":"open"
}