I have stored JSON data in a string and by using the JObject, I am trying to get values from JSON data. I am just not able to figure out that what is the underlying issue with my code because I am not able to get data from the JSON object. A snippet of my code is attached below. If some can help me out to figure out the issue it will be immensely appreciated.
String text;
try {
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
JObject jObject = JObject.Parse(text);
string haha = (string)jObject["value/segments/requests/count/sum"];
ViewBag.gotstring = haha;
}
System.Diagnostics.Debug.WriteLine(text);
} catch(Exception e) {
System.Diagnostics.Debug.WriteLine(url);
System.Diagnostics.Debug.WriteLine(e.ToString()); }
return View();
Here is the JSON:
{
"value": {
"start": "2018-08-12T04:44:38.941Z",
"end": "2018-08-12T16:44:38.941Z",
"interval": "PT30M",
"segments": [
{
"start": "2018-08-12T14:00:00Z",
"end": "2018-08-12T14:30:00Z",
"segments": [
{
"requests/count": {
"sum": 2
},
"request/name": "GET Home/Index"
},
{
"requests/count": {
"sum": 1
},
"request/name": "GET Home/About"
},
{
"requests/count": {
"sum": 1
},
"request/name": "GET Home/Contact"
}
]
},
{
"start": "2018-08-12T14:30:00Z",
"end": "2018-08-12T15:00:00Z",
"segments": [
{
"requests/count": {
"sum": 2
},
"request/name": "GET Account/Register"
},
{
"requests/count": {
"sum": 1
},
"request/name": "GET Account/Login"
}
]
},
{
"start": "2018-08-12T15:30:00Z",
"end": "2018-08-12T16:00:00Z",
"segments": [
{
"requests/count": {
"sum": 8
},
"request/name": "GET Home/Index"
},
{
"requests/count": {
"sum": 8
},
"request/name": "GET Home/About"
}
]
}
]
}
}
jObject does not work this way. It returns dictionary that you can query by key, but keys are single level. I.e. you'll be able to get some data like this:
var haha = jObject["value"]["segments"];
But beyond that it gets very complex. You'll be much better off defining a C# class that represents your JSON and serialise into that. A simple `Edit=>Paste Special => JSON as Class" in Visual Studio gives this:
public class Rootobject
{
public Value value { get; set; }
}
public class Value
{
public DateTime start { get; set; }
public DateTime end { get; set; }
public string interval { get; set; }
public Segment[] segments { get; set; }
}
public class Segment
{
public DateTime start { get; set; }
public DateTime end { get; set; }
public Segment1[] segments { get; set; }
}
public class Segment1
{
[JsonProperty("requests/count")]
public RequestsCount requestscount { get; set; }
[JsonProperty("request/name")]
public string requestname { get; set; }
}
public class RequestsCount
{
public int sum { get; set; }
}
and then deserialise like this:
var serialised = JsonConvert.DeserializeObject<Rootobject>(json);
var haha = serialised.value.segments.FirstOrDefault().segments.FirstOrDefault().requestscount.sum;
And here is a working sample: https://dotnetfiddle.net/CZgMNE
Can you try:
EDIT: seems like segments is an array, this will get you the sum for first segment only
string haha = (string)jObject["value"]["segments"][0]["segments"]["requests/count"]["sum"];
Related
{
Items: [
{
"title": "Object1",
"preview": {
"2048": "preview_9212.jpg",
"1024": "preview_6693.jpg",
}
},
{
"title": "Object2",
"preview": {
"2048": "preview_9888.jpg",
"1024": "preview_6890.jpg",
}
},
{
"title": "Object3",
"preview": {
"2048": "preview_9822.jpg",
"1024": "preview_6848.jpg",
}
}
]
}
I usually deserialise like this:
[Serializable]
public class JsonParser
{
public string title;
public List<Preview> preview;
}
[Serializable]
class Preview
{
public string 2048;
}
But since 2048 is an Integer is not possible to use this way.
I tried to deserialize the JSON to get preview like these:
public class Preview
{
[JsonProperty("2048")]
public string imageNumber { get; set; }
}
var user = JsonConvert.DeserializeObject<Preview>(jsonValue);
or
var json = JObject.Parse(jsonValue);
var preview = json["preview"].ToObject<Dictionary<string, string>>();
foreach (var entry in preview)
{
Debug.Log(entry.Key);
Debug.Log(entry.Value);
}
I got: NullReferenceException: Object reference not set to an instance of an object.
I also tried Deserializing JSON that has an int as a key in C# but again NullReferenceException;
Thanks for any help!
Since you have numeric string properties, you have 2 main choices:
Use something like [JsonProperty("2048")] and select valid name for the property
Or use a dictionary. This looks much more flexible for me, so you can try this code
Data data= JsonConvert.DeserializeObject<Data>(json);
string preview2048 = data.Items[0].Preview["2048"]; //preview_9212.jpg
or more complicated search using Linq
string obj3Preview2048 = data.Items.Where(i=> i.Title == "Object3")
.Select(i =>i.Preview["2048"]).FirstOrDefault(); //preview_9822.jpg
classes
public partial class Data
{
[JsonProperty("Items")]
public List<Item> Items { get; set; }
}
public partial class Item
{
[JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
public string Title { get; set; }
[JsonProperty("token")]
public string Token { get; set; }
[JsonProperty("preview")]
public Dictionary<string, string> Preview { get; set; }
}
and you have some typos in json you posted, and I fix "type" to "title" in one of json objects. This is a fixed version
{
"Items": [{
"title": "Object1",
"token": "6561b1bbe5f1958848jhgd43d2",
"preview": {
"2048": "preview_9212.jpg",
"1024": "preview_6693.jpg"
}
},
{
"title": "Object2",
"token": "4a42eb54648DSFhUI664654d25",
"preview": {
"2048": "preview_9888.jpg",
"1024": "preview_6890.jpg"
}
},
{
"type": "Object3",
"token": "3fba64831dghkjgfkl5dfaegoj9",
"preview": {
"2048": "preview_9822.jpg",
"1024": "preview_6848.jpg"
}
}
]
}
I am trying to deserialise the live chat api json response to access the message id and text by filtering using user_type
JSON response
{{
"events": [
{
"type": "agent_details",
"message_id": 1,
"timestamp": 1532396384,
"user_type": "agent",
"agent": {
"name": "Adam Harris",
"job_title": "Support Agent",
"avatar": "livechat.s3.amazonaws.com/default/avatars/ab5b0666feffd67600206cd519fd77ea.jpg"
}
},
{
"type": "message",
"message_id": 3,
"timestamp": 1532396387,
"user_type": "visitor",
"text": "hi"
}
]
}}
JsonOject Class
class JsonLiveChatEvent
{
public class Rootobject
{
public Event[] events { get; set; }
}
public class Event
{
public string type { get; set; }
public int message_id { get; set; }
public int timestamp { get; set; }
public string user_type { get; set; }
public Agent agent { get; set; }
public string text { get; set; }
}
public class Agent
{
public string name { get; set; }
public string job_title { get; set; }
public string avatar { get; set; }
}
}
JsonConverter
string jsonStr= await Api.Chat.GetPendingMessages(visitorID, licenseID,
var chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
The chatEvent object will not let me call chatEvent.events.message_id for example. Any help would be greatly appreciated as this is my first time working with json in c#
There is nothing to do with JSON, you have parsed the JSON data back to Rootobject.
Now you are working with an instance of Rootobject as:
Rootobject chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
Event event1 = chatEvent.events[0];
Event event2 = chatEvent.events[1];
Also, consider the answer from Mohammad, because above JSON will throw an exception.
The main problem here is that your json is not valid, there is an extra { in the beginning and an extra } in the end.
Then you could deserialize your json with the types you provided
Your json contains more that one curly brackets so you have to first remove those
so your json look like
{
"events": [
{
"type": "agent_details",
"message_id": 1,
"timestamp": 1532396384,
"user_type": "agent",
"agent": {
"name": "Adam Harris",
"job_title": "Support Agent",
"avatar": "livechat.s3.amazonaws.com/default/avatars/ab5b0666feffd67600206cd519fd77ea.jpg"
}
},
{
"type": "message",
"message_id": 3,
"timestamp": 1532396387,
"user_type": "visitor",
"text": "hi"
}
]
}
After that you have to collect message ids depending upon user_type
So then we create enum for that
public enum UserType
{
agent, visitor
}
then we simply check in events that if user type is matches with any of above enum value.
If your json contains multiple events with multiple user types then collect those into List<int>.
If your json contains only single event of each user type then collect them into string variables.
Rootobject chatEvent = JsonConvert.DeserializeObject<Rootobject>(jsonStr);
List<int> agent_message_ids = new List<int>();
List<int> visitior_message_ids = new List<int>();
//string agent_message_id = string.Empty;
//string visitior_message_id = string.Empty;
foreach (Event e in chatEvent.events)
{
if (e.user_type == UserType.agent.ToString())
{
agent_message_ids.Add(e.message_id);
//agent_message_id = e.message_id;
}
if (e.user_type == UserType.visitor.ToString())
{
visitior_message_ids.Add(e.message_id);
//visitior_message_id = e.message_id;
}
}
We simply take a list of integers that store message ids for particular user_type
Try once may it help you
Result:
agent_message_ids:
visitor_message_ids:
public static string DeserializeNames()
{
// Json I am passing for the deserialization.
JsonStream= "{
"head": {
"Rows": [
"test 1",
[
[
{
"#Key": "Domain",
"#value": "LocalHost"
},
{
"#Key": "Cookie name(s)",
"#value": "Google"
},
{
"#Key": "Purpose",
"#value": "Test"
},
{
"#Key": "lifetime",
"#value": "test"
}
]
]
]
}
}"
//deserialize JSON from file
JavaScriptSerializer serializer = new JavaScriptSerializer();
var cookieList = serializer.Deserialize<List<Cookie>>(JsonStream).ToList();
}
//Class descriptions
//I have created below classes for the deserialization. Records are not deserialized i am getting zero record count.
public class Categorization
{
public string categorizationName { get; set; }
public List<object> KeyValue{ get; set; }
}
public class Head
{
public IList<Categorization> Rows { get; set; }
}
public class Cookie
{
public Head head { get; set; }
}
Also created below set of the classes and tried the deserialization, Still no luck
public class Head
{
public List<object> Rows { get; set; }
}
public class Cookie
{
public Head head { get; set; }
}
I am getting count as 0 i am not able to fetch any record.
Please help !!
I have modified the Json as below and stored in in the file "test.json" :
{
"head": {
"TestRows": [
[
{
"Key": "Domain",
"value": "Google"
},
{
"Key": "Cookie",
"value": "Test"
},
{
"Key": "Use for",
"value": "Test."
},
{
"Key": "Expire Time",
"value": "1 hour"
}
]
]
}
}
And created below set of classes :
public class Head
{
public IList<List<Dictionary<string, object>>> TestRows{ get; set; }
}
public class Cookie
{
public Head Head { get; set; }
}
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var path= Path.Combine(baseDirectory, "test.json");
//deserialize JSON from file
string JsonStream = System.IO.File.ReadAllText(path, Encoding.Default);
var DeserializedCookieList = JsonConvert.DeserializeObject<Cookie>(JsonStream);
Deserialization is working properly.
ok so im not entirely sure how to explain this but ill give it my best shot. i have deserialisation from json working on singular objects, but when i get a list of the objects in json form, it doesnt work, and there are a few extra details outside of the singular objects when in a list of the objects.
the line of code im pretty sure is the problem is
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(JObject.Parse(json).ToString());
but i cannot figure out how to solve it.
anyway.
this is where the multiple data objects in json from come from:
public static async Task<DeserializedObjects.BlockList> GetUpToTenBlocks(int height)
{
var JData = (dynamic)new JObject();
JData.height = height;
String uri = String.Concat(partialApi, "/local/chain/blocks-after");
var response = await client.PostAsync(uri, new StringContent(JData.ToString(), Encoding.UTF8, "application/json"));
var content = response.Content;
{
var json = await content.ReadAsStringAsync();
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(JObject.Parse(json).ToString());
Console.WriteLine(model.AtIndex[1].difficulty);
return model;
}
}
which is deserialized to:
public class PrevBlockHash
{
public string data { get; set; }
}
public class Block
{
public int timeStamp { get; set; }
public string signature { get; set; }
public PrevBlockHash prevBlockHash { get; set; }
public int type { get; set; }
public List<object> transactions { get; set; }
public int version { get; set; }
public string signer { get; set; }
public long height { get; set; }
}
public class Datum
{
public object difficulty { get; set; }
public List<object> txes { get; set; }
public Block block { get; set; }
public string hash { get; set; }
}
public class BlockList
{
public List<Datum> AtIndex { get; set; }
}
and this is the json payload:
{
"data": [
{
"difficulty": 11763927507942,
"txes": [],
"block": {
"timeStamp": 167479,
"signature": "bb062d9b5f132b39b9e56de2413bf04928af009587446621da7afd351d
15a2ce7b5504450acf41bc3b19ab71e9bf34722005239d93f05a2318130f85118df40c",
"prevBlockHash": {
"data": "d4875ad2fc74dacfa89a13f24159d14555d3766f4fe2d708a7596f84eba88
31b"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "00a30788dc1f042da959309639a884d8f6a87086cda10300d2a7c3a0e0891
a4d",
"height": 1001
},
"hash": "f70898011d7343a0823de9c9cf263de29ddf2c16bb78cea626b9af90ea7ec260"
},
{
"difficulty": 11625594628802,
"txes": [],
"block": {
"timeStamp": 167561,
"signature": "116dedf43dd06b9ca634db0e20e06cc93337cdba155bced4d843ece4cc
9a57487d58e9a34d8a0e19bf71d3b7facb15179a87767f0063ebbce7c940cd545d5f01",
"prevBlockHash": {
"data": "f70898011d7343a0823de9c9cf263de29ddf2c16bb78cea626b9af90ea7ec
260"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "6ecd181da287c9ccb0075336de36427f25cbc216dc6b1f0e87e35e41a39f6
3fe",
"height": 1002
},
"hash": "77b5644c35e0d0d51f8bb967d0d92e0ddb03c4ede6632cb3b7651b7394617562"
},
{
"difficulty": 11538802895169,
"txes": [],
"block": {
"timeStamp": 167624,
"signature": "982574132fdc99b6f484acdd3f1cb5229b2bf78ad7b4e9af3d7a1873da
b987401f8bf808ff749aca70c503f490db1411b6cd89dbb0c1daa24fd580f91d3d9601",
"prevBlockHash": {
"data": "77b5644c35e0d0d51f8bb967d0d92e0ddb03c4ede6632cb3b7651b7394617
562"
},
"type": 1,
"transactions": [],
"version": 1744830465,
"signer": "26a3ac4b24647c77dc87780a95e50cb8d7744966e4569e3ac24e52c532c0c
d0d",
"height": 1003
},
"hash": "1a6d52c6317150d1839790da2c1481d714038c869842f769affbec0fdeec9861"
}
]
}
Try this:
var model = JsonConvert.DeserializeObject<DeserializedObjects.BlockList>(json);
Console.WriteLine(model.data[1].difficulty);
along with, also:
public class BlockList
{
public List<Datum> data { get; set; }
}
Okay first of all, the answer is probably very simple... But after 45 minutes of trying and googling I just can't figure it out!
So I have some problems getting this Json to parse correctly. I created the classes with http://json2csharp.com/ only it doesn't tell me the code to parse it.
My current classes:
public class Representations
{
public string thumb { get; set; }
public string large { get; set; }
public string full { get; set; }
}
public class Search
{
public string id { get; set; }
public string file_name { get; set; }
public Representations representations { get; set; }
}
public class SearchQuery
{
public List<Search> search { get; set; }
public int total { get; set; }
}
JSON:
{
"search": [
{
"id": "0300",
"file_name": "0300.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0300.jpg"
},
},
{
"id": "0000",
"file_name": "0000.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0000.jpg"
},
},
{
"id": "0d00",
"file_name": "0d00.JPG",
"representations": {
"thumb": "thumb.jpg",
"large": "large.jpg",
"full": "0d00.jpg"
},
}
],
"total": 3
}
and code:
searchresults = JsonConvert.DeserializeObject<List<SearchQuery>>(JSONCode);
You should deserialize to a SearchQuery, not List<SearchQuery>:
SearchQuery result = JsonConvert.DeserializeObject<SearchQuery>(JSONCode);
and then use the search property to access the list of search results:
List<Search> searchResults = result.search;