I'm trying to deserialize a JSON response in c# using Newtonsoft.Json
Here is an example of the type of JSON response I'm working with:
{
"version": "1.0",
"fixes": [
{
"fix1": "this is fix 1",
"fix2": "this is fix 2",
"fix3": "this is fix 3"
}
]
}
In this response there can be any number of "fixes."
My object class looks like this:
public class Update
{
public class Fix
{
public IDictionary<string, string> Values { get; set; }
}
public class Root
{
public string version { get; set; }
public List<Fix> fixes { get; set; }
}
}
Here I'm deserializing the http response and trying to get value of fixes, but all of the values are null:
var root = JsonConvert.DeserializeObject<Update.Root>(strContent);
Update.Fix fixes = root.fixes[0];
foreach (var fix in fixes.Values)
{
string test = fix.Value.ToString();
}
Eliminate the class Fix. In Root have public List<Dictionary<string, string>> fixes { get; set; }:
public class Root
{
public string version { get; set; }
public List<Dictionary<string, string>> fixes { get; set; }
}
Then, to loop through all the keys and values, you can use SelectMany() to project the list of dictionaries to an enumerable of key/value pairs:
foreach (var pair in root.fixes.SelectMany(p => p))
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
Demo fiddle here.
your fixes are a dictionary, not a collection, but you can convert it to a collecton
List<string> fixes = JObject.Parse(json)["fixes"]
.SelectMany(jo => ((JObject)jo).Properties()
.Select(p => (string) p.Value))
.ToList();
foreach (string fix in fixes)
{
Console.WriteLine(fix);
}
output
this is fix 1
this is fix 2
this is fix 3
or dictionary
Dictionary<string, string> fixes = JObject.Parse(json)["fixes"]
.Select(jo => jo.ToObject<Dictionary<string, string>>())
.FirstOrDefault();
foreach (var fix in fixes)
{
Console.WriteLine(fix.Key + " : " + fix.Value);
}
output
fix1 : this is fix 1
fix2 : this is fix 2
fix3 : this is fix 3
Related
I am looking to parse JSON into a C# List. The problem is that the data I am trying to parse is not coming in Array format. Following is the sample JSON
{
"results":{
"records":{
"record:8545314564":{
"name":"record 1",
"description":"description for record 1"
},
"record:2254698789":{
"name":"record 2",
"description":"description for record 2"
},
"record:7454687851":{
"name":"record 3",
"description":"description for record 3"
}
}
}
}
My Model class looks something like this
public class Record
{
public string Name { get; set; }
public string Description { get; set; }
}
What I am looking for is to create a
List<Record> Records
I don't care about the name of the records child node (i.e record:8545314564, record:2254698789 etc). All I care about is the name and description property inside each record node.
I would really appreciate if someone can please provide a sample code in C# to achieve this desired output.
And another alternative:
using Newtonsoft.Json.Linq;
...
var jObject = JObject.Parse(yourJsonString);
var records = jObject["results"]["records"]
.Children()
.Children()
.Select(i => i.ToObject<Record>())
.ToList();
You can find relevant Json.NET documentation here:
https://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm
By using a Dictionary, you can use a dynamic record name as a key.
public class Root
{
[JsonProperty("results")]
public Result Results { get; set; }
}
public class Result
{
[JsonProperty("records")]
public Dictionary<string, Record> Records { get; set; }
}
public class Record
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
}
var data = JsonConvert.DeserializeObject<Root>(json);
You could do the following.
var result = JsonConvert.DeserializeObject<RootObject>(jsonString);
var recordCollection = result.results.records.Values.ToList();
Where RootObject is defined as
public class RootObject
{
public ResultObject results { get; set; }
}
public class ResultObject
{
public Dictionary<string, RecordObject> records { get; set; }
}
public class RecordObject
{
public string name { get; set; }
public string description { get; set; }
}
Output
You can parse the Json and then iterate through the tokens for each property value.
// assuming json is your json string
JObject obj = JObject.Parse(json);
JToken sec = obj["results"]["records"];
foreach (JToken token in sec)
{
string name = token.First()["name"].ToString();
string description = token.First()["description"].ToString();
}
I'm trying to make use of Netwonsoft.JSON.Linq in C#, to change the "statusCode" values in the following JSON:
{
"disbursements":[
{
"id":"1f337641",
"contactId":"f5eb2",
"statusCode":166000005,
"amount":8,
"category":166000001
},
{
"id":"027a4762",
"contactId":"f5eb2038",
"statusCode":166000000,
"amount":4000,
"category":166000000
}
]
}
So, inside the JSON data is: "disbursements" which is JSON array. I have to change the "statusCode" of each item in the array to 166000005. I'm able to retrieve statusCode of the first one using
JObject jsonText = JObject.Parse(bodyText);
var statusCode = (int)jsonText.SelectToken("disbursements[0].statusCode");
But I need a solution with loop or LINQ that changes all the values, not just the first.
The following code sets or adds "statusCode": 166000005 to every entry in the disbursement array:
var jsonText = JObject.Parse(bodyText);
foreach (var disbursement in jsonText.SelectTokens("disbursements[*]"))
{
disbursement["statusCode"] = 166000005;
}
Notes:
The query string "disbursements[*]" contains the JSONPath wildcard operator [*]. This operator matches all array elements under the parent element "disbursement".
Json.NET supports JSONPath syntax as documented in Querying JSON with JSONPath.
SelectTokens() is used rather than SelectToken() to loop through multiple possible matches.
The JToken item setter disbursement["statusCode"] = 166000005 will replace the "statusCode" property if present and add it if not.
A simple, atomic value such as 166000005 can be set directly into a JToken hierarchy. For a complex POCO you would need to call JToken.FromObject() to serialize it to a JToken before setting it in the hierarchy, e.g.:
disbursement["statusCode"] =
JToken.FromObject( new { oldValue = disbursement["statusCode"], newValue = 166000005 } );
Sample working .Net fiddle.
I would create classes to represent the data. Here is my solution:
Create the data holder classes:
public class Disbursement
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("contactId")]
public string ContactId { get; set; }
[JsonProperty("statusCode")]
public int StatusCode { get; set; }
[JsonProperty("amount")]
public int Amount { get; set; }
[JsonProperty("category")]
public int Category { get; set; }
}
The collection:
public class Disbursements
{
[JsonProperty("disbursements")]
public List<Disbursement> Items { get; set; } = new List<Disbursement>();
}
And then the loading / modifying / saving data:
class Program
{
static void Main(string[] args)
{
var disbursements =
JsonConvert.DeserializeObject<Disbursements>(
File.ReadAllText(
"data.json",
Encoding.UTF8
)
);
foreach (var disbursement in disbursements.Items)
{
disbursement.StatusCode = 166000005;
}
string modifiedContent = JsonConvert.SerializeObject(disbursements);
File.WriteAllText(
"modifiedData.json",
modifiedContent,
Encoding.UTF8
);
}
}
I have a dictionary of strings and object that i obtained deserializing this json answer:
{"labels":[{"id":"1","descrizione":"Etichetta interna","tipo":"0","template_file":"et_int.txt"},{"id":"2","descrizione":"Etichetta esterna","tipo":"1","template_file":"et_ext.txt"}],"0":200,"error":false,"status":200}
using the code:
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Now i want to loop only trought the objects inside the "labels" key.
I tried
foreach (var outer in labels["labels"]){/* code */}
but i got error:
CS1579: foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'.
Solved replacing the dictionary with a class, thank you
Create a class to deserialize your json:
To create classes, you can copy the json in clipboard and use the
Edit / Paste special / Paste JSON as class
in visual studio (I use vs2013).
[TestMethod]
public void test()
{
string json = "{\"labels\" : [{\"id\" : \"1\",\"descrizione\" : \"Etichetta interna\",\"tipo\" : \"0\",\"template_file\" : \"et_int.txt\"}, {\"id\" : \"2\",\"descrizione\" : \"Etichetta esterna\",\"tipo\" : \"1\",\"template_file\" : \"et_ext.txt\"}],\"0\" : 200,\"error\" : false,\"status\" : 200}";
var root = JsonConvert.DeserializeObject<Rootobject>(json);
foreach (var label in root.Labels)
{
//Use label.Id, label.Descrizione, label.Tipo, label.TemplateFile
}
}
public class Rootobject
{
public Label[] Labels { get; set; }
public int _0 { get; set; }
public bool Error { get; set; }
public int Status { get; set; }
}
public class Label
{
public string Id { get; set; }
public string Descrizione { get; set; }
public string Tipo { get; set; }
public string TemplateFile { get; set; }
}
You need to loop through your dictionary.
foreach(KeyValuePair<string, Object> entry in labels)
{
// do something with entry.Value or entry.Key
}
Once you start looping through it you will get access to key and value. Since you are interested to look at entry.value you can do operation on that easily. Currently your dictionary value is type of object which does not have an enumerator
Your problem is that you've defined the Type of Value for each dictionary entry as object. C# can't know how to loop over on object. So you need to work out what type is actually inside the object once the JavaScriptSerializer have parsed the JSON. One way is
var t = typeof(labels["labels"]);
Once you know what type the serializer is creating, all you need to do is cast the object back to that type. For example, assuming it's a list of objects
var labels = (List<object>)labels["labels"];
foreach (var label in labels)
{
}
Alternatively, if each object in the JSON is the same, you could try create the dictionary as the type you need. So you serializing becomes
var labels = new JavaScriptSerializer()
.Deserialize<Dictionary<string, List<object>>>(json);
A possible solution:
static void Main(string[] args) {
string json = #"{'labels':[{'id':'1','descrizione':'Etichetta interna','tipo':'0','template_file':'et_int.txt'},{'id':'2','descrizione':'Etichetta esterna','tipo':'1','template_file':'et_ext.txt'}],'0':200,'error':false,'status':200}";
var labels = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
IEnumerable inner_labels = labels["labels"] as IEnumerable;
if (inner_labels != null) {
foreach (var outer in inner_labels) {
Console.WriteLine(outer);
}
}
}
Otherwise, you can create a class with deserialization information and instruct the deserializer to deserialize your json string to that type:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
[Serializable]
public class JsonData {
[XmlElement("labels")]
public List<JsonLabel> labels { get; set; }
[XmlElement("0")]
public int zero { get; set; }
[XmlElement("error")]
public bool error { get; set; }
[XmlElement("status")]
public int status { get; set; }
}
[Serializable]
public class JsonLabel {
[XmlElement("id")]
public int id { get; set; }
[XmlElement("descrizione")]
public string descrizione { get; set; }
[XmlElement("tipo")]
public int tipo { get; set; }
[XmlElement("template_file")]
public string template_file { get; set; }
}
class Program {
static void Main(string[] args) {
string json = #"your json string here...";
var jsonData = new JavaScriptSerializer().Deserialize<JsonData>(json);
foreach (var label in jsonData.labels) {
Console.WriteLine(label.id);
}
}
}
Could you please try below snippet?
It might be help you.
foreach (var item in labels["labels"] as ArrayList)
{
Console.Write(item);
}
I want to convert a json string to NameValueCollection. I came up with the code below.
public static NameValueCollection ConvertFromJson(string json)
{
var anonymous = JContainer.Parse(json);
var nvc = new NameValueCollection();
var dict = new RouteValueDictionary(anonymous);
foreach (var kvp in dict)
{
if (kvp.Value == null)
{
// I am OK if a property is null. Just skip it.
continue;
}
if (kvp.Value.GetType().Name.Contains("Anonymous"))
{
var prefix = kvp.Key + ".";
foreach (var innerkvp in new RouteValueDictionary(kvp.Value))
{
nvc.Add(prefix + innerkvp.Key, innerkvp.Value.ToString());
}
}
else
{
nvc.Add(kvp.Key, kvp.Value.ToString());
}
}
return nvc;
}
It works well with normal classes but not nested classes. For example, it works with class A but not class B.
class A
{
public string AAA { get; set; }
public int BBB { get; set; }
}
class B
{
public string AAA { get; set; }
public MyOtherClass BBB { get; set; }
}
How can I convert nested objects to NameValueCollection?
Explain
This question is absolutely not duplicate with How to convert json to NameValueCollection. The answer in that question only works with class A but it does not work with class B.
If you only whant to serialise/deserialise a nested object like you shared on the question you could use a work around like this:
Dictionary <string, object> deserializedresult = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
The only problem with it that you need to serialise and desrialise again the nested objects or use reflection to reach the contained elements of the nested objects.
I am trying for many hours to parse a JsonArray, I have got by graph.facebook, so that i can extra values. The values I want to extract are message and ID.
Getting the JasonArry is no Problem and works fine:
[
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_1\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the first message\",
\"created_time\":\"2011-11-04T21:32:50+0000\"}"},
{
"code":200,
"headers":[{"name":"Access-Control-Allow-Origin","value":"*"}],
"body":"{
\"id\":\"255572697884115_2\",
\"from\":{
\"name\":\"xyzk\",
\"id\":\"59788447049\"},
\"message\":\"This is the second message\",
\"created_time\":\"2012-01-03T21:05:59+0000\"}"}
]
Now I have tried several methods to get access to message, but every method ends in catch... and throws an exception.
For example:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach (var item in result)
{
Console.WriteLine(item.body.message);
}
throws the exception: System.Collections.Generic.Dictionary doesnt contain definitions for body. Nevertheless you see in the screenshot below, that body contains definitions.
Becaus I am not allowed to post pictures you can find it on directupload: http://s7.directupload.net/images/120907/zh5xyy2k.png
I don't havent more ideas so i please you to help me. I need this for a project, private, not commercial.
Maybe you could give me an phrase of code, so i can continue my development.
Thank you so far
Dominic
If you use Json.Net, All you have to do is
replacing
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
with
dynamic result = JsonConvert.DeserializeObject(json);
that's all.
You are not deserializing to a strongly typed object so it's normal that the applications throws an exception. In other words, the deserializer won't create an Anynymous class for you.
Your string is actually deserialized to 2 objects, each containing Dictionary<string,object> elements. So what you need to do is this:
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(s);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
Here's a complete sample code:
void Main()
{
string json = #"[
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_1"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the first message"",
""created_time"":""2011-11-04T21:32:50+0000""}},
{
""code"":200,
""headers"":[{""name"":""Access-Control-Allow-Origin"",""value"":""*""}],
""body"":{
""id"":""255572697884115_2"",
""from"":{
""name"":""xyzk"",
""id"":""59788447049""},
""message"":""This is the second message"",
""created_time"":""2012-01-03T21:05:59+0000""}}
]";
var serializer = new JavaScriptSerializer();
var result = serializer.Deserialize<dynamic>(json);
foreach(var item in result)
{
Console.WriteLine(item["body"]["message"]);
}
}
Prints:
This is the first message
This is the second message
I am using this simple technique
var responseTextFacebook =
#"{
"id":"100000891948867",
"name":"Nishant Sharma",
"first_name":"Nishant",
"last_name":"Sharma",
"link":"https:\/\/www.facebook.com\/profile.php?id=100000891948867",
"gender":"male",
"email":"nihantanu2010\u0040gmail.com",
"timezone":5.5,
"locale":"en_US",
"verified":true,
"updated_time":"2013-06-10T07:56:39+0000"
}"
I have declared a class
public class RootObject
{
public string id { get; set; }
public string name { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string link { get; set; }
public string gender { get; set; }
public string email { get; set; }
public double timezone { get; set; }
public string locale { get; set; }
public bool verified { get; set; }
public string updated_time { get; set; }
}
Now I am deserializing
JavaScriptSerializer objJavaScriptSerializer = new JavaScriptSerializer();
RootObject parsedData = objJavaScriptSerializer.Deserialize<RootObject>(responseTextFacebook );