Unable to parse JSON with multiple JObjects - c#

I am having a string in the following format. I want to assign each JSON within the projects to a separate JObject. When I am trying to parse it and assign accordingly, I am unable to achieve it. How can I parse it?
{
"projects": [
{
"sno": "1",
"project_name": "Abs",
"project_Status": "Live"
},
{
"sno": "2",
"project_name": "Cgi",
"project_Status": "Live"
}
]
}
I have tried the following code;
using (StreamReader streamReader = new StreamReader(Path.Combine(Path.GetTempPath(), "sample.json")))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
JObject jsonPayload = JObject.Load(reader);
jsonProfile = jsonPayload.ToString();
JObject json = JObject.Parse(jsonProfile);
}
}
}

you can use DeserializeAnonymousType as a simpler solution to parse json.
var definition = new
{
projects = new[]{
new {
sno="1",
project_name= "Abs",
project_Status= "Live"
}
}
};
string json1 = #" {
'projects': [
{
'sno': '1',
'project_name': 'Abs',
'project_Status': 'Live'
},
{
'sno': '2',
'project_name': 'Cgi',
'project_Status': 'Live'
}
]
}";
var projects = JsonConvert.DeserializeAnonymousType(json1, definition);
but if you do want to use strong type, you'd better to use JsonProperty
public class Project
{
[JsonProperty("sno")]
public string Sno { get; set; }
[JsonProperty("project_name")]
public string ProjectName { get; set; }
[JsonProperty("project_Status")]
public string ProjectStatus { get; set; }
}
public class JsonModel
{
[JsonProperty("Projects")]
public List<Project> projects { get; set; }
}
JsonConvert.DeserializeObject<JsonModel>(json_Data);

Related

Extract array from JSON object containing multiple types

(Just a heads up, I'm very new to C#)
(See sample code and JSON structure below)
I can't figure out how to pull "data" out of the JSON reponse and put it into a data table. The variable "response" is just raw JSON data. So far I've figured out how to parse the JSON into a JObject...so now it has two members (data, meta). Now I'm trying to figure out how to get joTest["data"] into a DataTable. The handful of attempts I've made, keep giving me an error when it sees the "meta" member. Maybe I shouldn't be using a Data Table?
Also, in case it changes anything, I don't need the "links" from the "data" members.
I've tried searching for "Converting JObject into Data Table" But I'm not finding a lot of useful results.
public void PerformFeed()
{
string response;
response = Blah.SendMessage().Result;
JObject joTest = JsonConvert.DeserializeObject<JObject>(response);
}
Json Data Structure
{
"data": [
{
"Val1": "1234",
"Val2": "foo1",
"Val3": "bar1",
"links": [
{
"rel": "self",
"uri": "/blah/1234"
},
{
"rel": "pricing_data",
"uri": "/blah/1234/pricing_data"
}
]
},
{
"Val1": "5678",
"Val2": "foo2",
"Val3": "bar2",
"links": [
{
"rel": "self",
"uri": "/blah/5678"
},
{
"rel": "pricing_data",
"uri": "/blah/5678/pricing_data"
}
]
}
],
"meta": {
"pagination": {
"total": 2,
"count": 2,
"per_page": 25,
"current_page": 1,
"total_pages": 1,
"links": []
}
}
}
UPDATE: I've figured out a "solution" but I really don't think it's a good solution. I built a datatable and then used a foreach statement on the JObject to populate the data table that way. It seems very inefficient...but for now it works. Hopefully I'll find a better way.
public void PerformFeed()
{
DataTable Items = new DataTable();
Items.Columns.Add("Val1");
Items.Columns.Add("Val2");
Items.Columns.Add("Val3");
string response = Blah.SendMessage().Result;
JObject Data = JObject.Parse(response);
foreach (JObject jo in Data["data"])
{
Items.Rows.Add(jo["Val1"], jo["Val2"], jo["Val3"]);
}
}
There is this really nice online utility that helps extracting C# classes from JSON objects. I think the problem here is with your JSON, you're missing a comma ",". You would easily be able to spot the error with some online JSON formatter / validator. Rest the deserialization is pretty straightforward. Try the following:
JObject obtainedObject = JObject.Parse(JsonString);
Following would be the structure of your obtained object:
public class RequiredClass
{
public IList<Datum> data { get; set; }
public Meta meta { get; set; }
}
public class Datum
{
public string Val1 { get; set; }
public string Val2 { get; set; }
public string Val3 { get; set; }
public IList<Link> links { get; set; }
}
public class Link
{
public string rel { get; set; }
public string uri { get; set; }
}
public class Pagination
{
public int total { get; set; }
public int count { get; set; }
public int per_page { get; set; }
public int current_page { get; set; }
public int total_pages { get; set; }
public IList<object> links { get; set; }
}
public class Meta
{
public Pagination pagination { get; set; }
}
Update:
Here's is how you extract your array and convert that to a DataTable:
JObject jObject = JObject.Parse(json);
JToken dataArray = jObject["data"];
DataTable dt = (DataTable) JsonConvert.DeserializeObject(dataArray.ToString(), (typeof(DataTable)));
To avoid the surplus casting, you can try the following using the class structure already mentioned above:
JObject jObject = JObject.Parse(json);
JToken dataArray = jObject["data"];
List<Datum> requiredList = new List<Datum>();
foreach (var item in dataArray)
{
Datum obj = new Datum();
obj.Val1 = (string) item["Val1"] ?? "";
obj.Val2 = (string) item["Val2"] ?? "";
obj.Val3 = (string) item["Val3"] ?? "";
obj.links = new List<Link>();
foreach(var subItem in item["links"])
{
Link lnk = new Link();
lnk.rel = (string) subItem["rel"] ?? "";
lnk.uri = (string) subItem["uri"] ?? "";
obj.links.Add(lnk);
}
requiredList.Add(obj);
}

Deserializing JSON to .NET

How to deserialize json of this kind into an object on C# ?
{
"AND":[
{
"AND":[
{
"AND":[
{
"AND":[
{
"AND":[
{
"AND":[
{
"OR":[
{
"OR":[
"Title",
"Login"
]
},
"LoginNote"
]
},
"BossTitle"
]
},
{
"OR":[
"Phone",
"TeleGorod"
]
}
]
},
"Room"
]
},
"Division"
]
},
"TabelnyiNomer"
]
},
"Filter\""
]
}
You can play with dynamic type, but I don't think it can help you.
class Program
{
static void Main(string[] args)
{
string unknownJson1 = "{\r\n \"Id\": \"1e4495d3-4cd1-4bf2-9da6-4acee2f7a70e\",\r\n \"Customers\": [\r\n \"Alice\",\r\n \"Bob\",\r\n \"Eva\"\r\n ]\r\n}";
string unknownJson2 = "{\"AND\": [\"_ x041f__x0435__x0440__x0432__x04\", {\"AND\": [\"_ x0418__x0437__x0433__x043e__x04\", {\"AND\": [\"_ x041e__x043f__x0438__x0441__x04\", {\"AND\": [\"_ x041a__x043e__x0434_\", \"Title\"]}]}]}] } ";
JsonSerializer serializer = new JsonSerializer();
dynamic deserializedObject;
using (var stringReader = new StringReader(unknownJson2))
{
using (var jsonReader = new JsonTextReader(stringReader))
{
deserializedObject = serializer.Deserialize(jsonReader);
}
}
Console.ReadKey(true);
}
}
quicktype's CLI supports JSON schema as an import format, which could help you represent the tree data structure you're parsing here. I'll look into why it wasn't detected automatically, but here's your model:
public class Tree
{
[JsonProperty("AND")]
public Leaf[] And { get; set; } // Could be null
[JsonProperty("OR")]
public Leaf[] Or { get; set; } // Could be null
}
public struct Leaf
{
public string String; // Could be null
public Top Tree; // Could be null
}
Your JSON should parse as this, although I haven't tested it.

How do deserialize JSON with non-standard (and varying) property names (in .NET)

I have to read a JSON stream (which I have no control over), which is in the form:
{"files":
{
"/some_file_path.ext": {"size":"1000", "data":"xxx", "data2":"yyy"},
"/other_file_path.ext": {"size":"2000", "data":"xxx", "data2":"yyy"},
"/another_file_path.ext": {"size":"3000", "data":"xxx", "data2":"yyy"},
}
}
So, I have an object named files, which has a number of properties, which have 1) different names every time, 2) different number of them every time, and 3) names with characters which can't be used in C# properties.
How do I deserialize this?
I'm putting this into a Portable Library, so I can't use the JavaScriptSerializer, in System.Web.Script.Serialization, and I'm not sure about JSON.NET. I was hoping to use the standard DataContractJsonSerializer.
UPDATE: I've changed the sample data to be closer to the actual data, and corrected the JSON syntax in the area the wasn't important. (Still simplified quite a bit, but the other parts are fairly standard)
You can model your "files" object as a Dictionary keyed by the JSON property name:
public class RootObject
{
public Dictionary<string, PathData> files { get; set; }
}
public class PathData
{
public int size { get; set; }
public string data { get; set; }
public string data2 { get; set; }
}
Then, only if you are using .Net 4.5 or later, you can deserialize using DataContractJsonSerializer, but you must first set DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true:
var settings = new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true };
var root = DataContractJsonSerializerHelper.GetObject<RootObject>(jsonString, settings);
With the helper method:
public static class DataContractJsonSerializerHelper
{
public static T GetObject<T>(string json, DataContractJsonSerializer serializer = null)
{
using (var stream = GenerateStreamFromString(json))
{
var obj = (serializer ?? new DataContractJsonSerializer(typeof(T))).ReadObject(stream);
return (T)obj;
}
}
public static T GetObject<T>(string json, DataContractJsonSerializerSettings settings)
{
return GetObject<T>(json, new DataContractJsonSerializer(typeof(T), settings));
}
private static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
}
}
Alternatively, you can install Json.NET and do:
var root = JsonConvert.DeserializeObject<RootObject>(jsonString);
Json.NET automatically serializes dictionaries to JSON objects without needing to change settings.
We need to first convert this Invalid JSON to a Valid JSON. So a Valid JSON should look like this
{
"files":
{
"FilePath" : "C:\\some\\file\\path",
"FileData" : {
"size": 1000,
"data": "xxx",
"data2": "yyy"
},
"FilePath" :"C:\\other\\file\\path",
"FileData" : {
"size": 2000,
"data": "xxx",
"data2": "yyy"
},
"FilePath" :"C:\\another\\file\\path",
"FileData" : {
"size": 3000,
"data": "xxx",
"data2": "yyy"
}
}
}
To make it a valid JSON we might use some string functions to make it looks like above. Such as
MyJSON = MyJSON.Replace("\\", "\\\\");
MyJSON = MyJSON.Replace("files", "\"files\"");
MyJSON = MyJSON.Replace("data:", "\"data:\"");
MyJSON = MyJSON.Replace("data2", "\"data2\"");
MyJSON = MyJSON.Replace(": {size", ",\"FileData\" : {\"size\"");
MyJSON = MyJSON.Replace("C:", "\"FilePath\" :\"C:");
Than we can create a class like below to read the
public class FileData
{
public int size { get; set; }
public string data { get; set; }
public string data2 { get; set; }
}
public class Files
{
public string FilePath { get; set; }
public FileData FileData { get; set; }
}
public class RootObject
{
public Files files { get; set; }
}
Assuming you have a valid JSON you could use JavaScriptSerializer to return a list of objects
string json = "{}"
var serializer = new JavaScriptSerializer();
var deserializedValues = (Dictionary<string, object>)serializer.Deserialize(json, typeof(object));
Alternatively you could specify Dictionary<string, List<string>> as the type argument
strign json = "{}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
var deserializedValues = serializer.Deserialize<Dictionary<string, List<string>>>(json);
foreach (KeyValuePair<string, List<string>> kvp in deserializedValues)
{
Console.WriteLine(kvp.Key + ": " + string.Join(",", kvp.Value));
}

How to get child objects from a JArray into an ObservableCollection

I am developing an app for Windows Phone, where a ListBox shows data from a JSON file. I'm using a JArray and I can display data according to an array position. But what if I want to display all data from my JSON file (the file doesn't have static data, and the data may be modified later)?
My JSON:
[
{
"xId": "52",
"result": {
"type": "Basico.Bean.MunicipioClass.TMunicipio",
"id": 1,
"fields": {
"FRefCount": 0,
"FId": 52,
"FNome": "Sumare",
"FEstado": "SP",
"FPais": "Brasil"
}
}
},
{
"xId": "52",
"result": {
"type": "Basico.Bean.MunicipioClass.TMunicipio",
"id": 1,
"fields": {
"FRefCount": 0,
"FId": 52,
"FNome": "Indaiatuba",
"FEstado": "SP",
"FPais": "Brasil"
}
}
}
]
My Code:
InitializeComponent();
String text;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var readStream = new IsolatedStorageFileStream("json.html", FileMode.Open, FileAccess.Read, FileShare.Read, store))
using (var reader = new StreamReader(readStream))
{
text = reader.ReadToEnd();
}
{
try
{
DataContext = this;
// Your JSON string
string json = text;
// Parse as JObject
JArray jObj = JArray.Parse(json);
// Extract what you need, the "fields" property
JToken jToken = jObj[0]["result"]["fields"];
// Convert as Fields class instance
Fields fields = jToken.ToObject<Fields>();
Items = new ObservableCollection<Fields>() { fields };
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public ObservableCollection<Fields> Items { get; set; }
public class Fields
{
[JsonProperty(PropertyName = "FId")]
public int FId { get; set; }
public string FNome { get; set; }
public string FEstado { get; set; }
public string FPais { get; set; }
}
When i used "[0]" the return is Sumare SP :
JToken jToken = jObj[0]["result"]["fields"];
When i used "[1]" the return is Indaiatuba SP :
JToken jToken = jObj[1]["result"]["fields"];
I need it like this:
Sumare SP
Indaiatuba SP
If I understand your question correctly, you are trying to get all of the "fields" objects from the JSON into your ObservableCollection<Fields>. Here is how you can do that:
JArray jObj = JArray.Parse(json);
Items = new ObservableCollection<Fields>(
jObj.Children().Select(jo => jo["result"]["fields"].ToObject<Fields>()));

How to get the values from list of objects in c#

I have Called a Json Web Service and got the result in c#.The Json Web service data is available in format:
{
"Count": 9862,
"Items": [
{
"Admin": {
"S": "false"
},
"UserId": {
"S": "e9633477-978e-4956-ab34-cc4b8bbe4adf"
},
"Age": {
"N": "76.24807963806055"
},
"Promoted": {
"S": "true"
},
"UserName": {
"S": "e9633477"
},
"Registered": {
"S": "true"
}
},
{
"Admin": {
"S": "false"
},
"UserId": {
"S": "acf3eff7-36d6-4c3f-81dd-76f3a8071bcf"
},
"Age": {
"N": "64.79224276370684"
},
"Promoted": {
"S": "true"
},
"UserName": {
"S": "acf3eff7"
},
"Registered": {
"S": "true"
}
},
I have got the Response like this in c#:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8000/userdetails");
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
after finally successfully get the response i have got all the Data in string. and then parse this string in list of objects .Now I have list of objects where it showing the count in debugging.Now I want to access the values like UserId:acf3eff7-36d6-4c3f-81dd-76f3a8071bcf like properties.I dont know how to do it.Please help me and any help will be appreciated.
You can use the following code to get the values from json as:
JObject obj = JObject.Parse(json);
int count = (int)obj["Count"];
var Items = obj["Items"];
foreach (var item in Items)
var admin = item["Admin"];
Quick and dirty way:
//deserialize your string json using json.net
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
//get value of UserId in first Item
var UserId = jsonObj["Items"][0]["UserId"]["S"];
//OR get the value of UserId for each Item in Items
//foreach(dynamic item in jsonObj["Items"])
//item["UserId"]["S"];
Advice is to use c# objects as mentioned by #yousuf
To be able to access Json property like common C# object property, you need to deserialize json string to strongly typed object (you can use, for example, JSON.NET to do deserialization).
Another handy tool is http://json2csharp.com/. Paste your Json there then you can generate classes definitions that suitable to map the Json automatically :
//RootObject class definition generated using json2csharp.com
//the rest of class definition removed for brevity.
public class RootObject
{
public int Count { get; set; }
public List<Item> Items { get; set; }
}
........
........
//in main method
var jsonString = .....;
//deserialize json to strongly-typed object
RootObject result = JsonConvert.DeserializeObject<RootObject>(jsonString);
foreach(var item in result.Items)
{
//then you can access Json property like common object property
Console.WriteLine(item.UserId.S);
}
you are deserializing string to c# object. you will need to create object that reperesents the json .
For example -
public class Admin
{
public string S { get; set; }
}
public class UserId
{
public string S { get; set; }
}
public class Age
{
public string N { get; set; }
}
public class Promoted
{
public string S { get; set; }
}
public class UserName
{
public string S { get; set; }
}
public class Registered
{
public string S { get; set; }
}
public class RootObject
{
public Admin Admin { get; set; }
public UserId UserId { get; set; }
public Age Age { get; set; }
public Promoted Promoted { get; set; }
public UserName UserName { get; set; }
public Registered Registered { get; set; }
}
Then deserialize json string to object using jsonSerializer
JavaScriptSerializer serializer = new JavaScriptSerializer();
var result =
(RootObject)serializer .DeserializeObject("Json String")
string json = #"{
""Name"": ""Apple"",
""Expiry"": new Date(1230422400000),
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
//This will be "Apple"
string name = (string)o["Name"];

Categories

Resources