Retrieve the values from json string - c#

I have json string. I want to retrieve the contact from json string. Following json contains array of contacts. here is my json string.
{
   "contacts": {
      "contact": [
         {
            "isConnection": false,
            "id": 33554611,
            "fields": [
               {
                  "id": 33554748,
                  "type": "name",
                  "value": {
                     "givenName": "Jhon",
                     "middleName": "",
                     "familyName": "Scot",
                     "prefix": "",
                     "suffix": "",
                     "givenNameSound": "",
                     "familyNameSound": ""
                  },
                  "editedBy": "OWNER",
                  "flags": [],
                  "categories": [],
                  "updated": "2012-12-23T07:40:23Z",
                  "created": "2012-12-23T07:40:23Z",
               },
               {
                  "id": 33554749,
                  "type": "email",
                  "value": "someone#example.com",
                  "editedBy": "OWNER",
                  "flags": [],
                  "categories": [],
                  "updated": "2012-12-23T07:40:23Z",
                  "created": "2012-12-23T07:40:23Z",
               }
            ]
         }
}
}
Here I want to retrieves the values of givenName,familyName,email. How can I retrieve the values of these from json string.
Note: there are array of contact in json. I have posted only one contact from this json.
I tried something like this. But not worked.
JObject json = JObject.Parse(returnStr);
JArray fields = (JArray)json["contacts"]["contact"]["fields"][0];
JArray FValues = (JArray)json["contact"]["fields"]["value"];
I tried this
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public List<object> flags { get; set; }
public List<object> categories { get; set; }
public string updated { get; set; }
public string created { get; set; }
public string uri { get; set; }
public bool? isConnection { get; set; }
}
public class contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
public List<object> categories { get; set; }
public int error { get; set; }
public int restoredId { get; set; }
public string created { get; set; }
public string updated { get; set; }
public string uri { get; set; }
}
public class Contacts
{
public List<contact> contact { get; set; }
public int count { get; set; }
public int start { get; set; }
public int total { get; set; }
public string uri { get; set; }
public bool cache { get; set; }
}
public class RootObject
{
public Contacts contacts { get; set; }
}
and
JavaScriptSerializer serializer1 = new JavaScriptSerializer();
RootObject obje = serializer1.Deserialize<RootObject>(returnStr);
But it is giving me 0 value in obje.

First make sure your Json is in valid format using jsonlint
Then generate class base on it using json2csharp
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public List<object> flags { get; set; }
public List<object> categories { get; set; }
public string updated { get; set; }
public string created { get; set; }
}
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
}
public class Contacts
{
public List<Contact> contact { get; set; }
}
public class RootObject
{
public Contacts contacts { get; set; }
}
Use Newtonsoft JSON to deserialize your Json into object(s) then you may simply access its properties value.
JsonConvert.DeserializeObject<RootObject>(string json);

Class for json object (generated with http://jsonutils.com/ after correcting some syntax error):
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public IList<object> flags { get; set; }
public IList<object> categories { get; set; }
public DateTime updated { get; set; }
public DateTime created { get; set; }
}
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public IList<Field> fields { get; set; }
}
public class Contacts
{
public IList<Contact> contact { get; set; }
}
public class Example
{
public Contacts contacts { get; set; }
}
Deserialization (you will probably need to add a reference to System.Web.Extensions):
System.Web.Script.Serialization.JavaScriptSerializer deSer = new System.Web.Script.Serialization.JavaScriptSerializer();
JSonPrintSettingsToXml.Input.Example deserializedJSON = deSer.Deserialize<JSonPrintSettingsToXml.Input.Example>(yourJSON);
Here is the corrected JSON
{
"contacts": {
"contact": [
{
"isConnection": false,
"id": 33554611,
"fields": [
{
"id": 33554748,
"type": "name",
"value": {
"givenName": "Jhon",
"middleName": "",
"familyName": "Scot",
"prefix": "",
"suffix": "",
"givenNameSound": "",
"familyNameSound": ""
},
"editedBy": "OWNER",
"flags": [],
"categories": [],
"updated": "2012-12-23T07:40:23Z",
"created": "2012-12-23T07:40:23Z"
},
{
"id": 33554749,
"type": "email",
"value": "someone#example.com",
"editedBy": "OWNER",
"flags": [],
"categories": [],
"updated": "2012-12-23T07:40:23Z",
"created": "2012-12-23T07:40:23Z"
}
]
}
]
}
}

You need to go with the following structure:
public class Contact
{
public bool isConnection { get; set; }
public int id { get; set; }
public List<Field> fields { get; set; }
}
public class Field
{
public int id { get; set; }
public string type { get; set; }
public object value { get; set; }
public string editedBy { get; set; }
public string[] flags { get; set; }
public string[] categories { get; set; }
public DateTime updated { get; set; }
public DateTime created { get; set; }
}
public class Name
{
public string givenName { get; set; }
public string middleName { get; set; }
public string familyName { get; set; }
public string prefix { get; set; }
public string suffix { get; set; }
public string givenNameSound { get; set; }
public string familyNameSound { get; set; }
}
And then deserialize it and use LINQ to manipulate fields.

If you want to stick to JObject and not create classes, look at the example provided at http://weblog.west-wind.com/posts/2012/Aug/30/Using-JSONNET-for-dynamic-JSON-parsing
You'll have to enumerate over this
dynamic contacts = (JArray)json["contacts"]
foreach(dynamic contact in contacts.contact) {
// look at the fields...
}
PS. Give it a go, don't have VS on me so cant quite verify the exact syntax

Firstly, I think you'll find that your JSON is not well-formed. You don't need the extra commas after the two "created" dates and there is a right-square bracket missing before the second last curly brace. I recommend you always validate your JSON using this awesome site: http://jsonformatter.curiousconcept.com
Secondly, you are not referencing the array elements correctly. Although I agree with #grundy that you should be creating class definitions for managing JSON and using LINQ, there is absolutely nothing wrong with the Newtonsoft library. You can still persist with your method.
Try this:-
var json = JObject.Parse(returnStr);
var fields = (JArray)json["contacts"]["contact"][0]["fields"];
var givenName = fields[0]["value"]["givenName"];
var familyName = fields[0]["value"]["familyName"];
var email = fields[1]["value"];

Related

JSON not deserializing as expected?

I have a collection of classes set out like this:
public class Xml
{
public string version { get; set; }
public string encoding { get; set; }
}
public class Content
{
public string Expires { get; set; }
public string MaxArrivalScope { get; set; }
}
public class Trip
{
public string ETA { get; set; }
public string TripNo { get; set; }
public string WheelchairAccess { get; set; }
}
public class Destination
{
public string Name { get; set; }
public List<Trip> Trip { get; set; }
}
public class Route
{
public string RouteNo { get; set; }
public string Name { get; set; }
public Destination Destination { get; set; }
}
public class Platform
{
public string PlatformTag { get; set; }
public string Name { get; set; }
public Route Route { get; set; }
}
public class JPRoutePositionET
{
public string xmlns { get; set; }
public string xsi { get; set; }
public string schemaLocation { get; set; }
public Content Content { get; set; }
public Platform Platform { get; set; }
}
public class RootObject
{
public Xml xml { get; set; }
public JPRoutePositionET JPRoutePositionET { get; set; }
}
}
I have JSON like this:
{
"xml": {
"version": "1.0",
"encoding": "utf-8"
},
"JPRoutePositionET": {
"xmlns": "urn:connexionz-co-nz:jp",
"xsi": "http://www.w3.org/2001/XMLSchema-instance",
"schemaLocation": "urn:connexionz-co-nz:jp JourneyPlanner.xsd",
"Content": {
"Expires": "2017-04-09T15:59:31+12:00",
"MaxArrivalScope": "60"
},
"Platform": {
"PlatformTag": "2628",
"Name": "Awatea Rd near Awatea Gdns",
"Route": {
"RouteNo": "125",
"Name": "Redwood/Westlake",
"Destination": {
"Name": "Westlake & Halswell",
"Trip": [
{
"ETA": "4",
"TripNo": "4751",
"WheelchairAccess": "true"
},
{
"ETA": "32",
"TripNo": "4752",
"WheelchairAccess": "true"
}
]
}
}
}
}
}
Why is Newtonsoft not parsing correctly to the Platform class? It returns null. Will I need to format the JSON to cut out all the other information I don't want? Or is it something I am missing?
Fabio's Comment of
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(js‌​onString);
Worked.
But now when I get JSON like pastebin.com/pebp178s I can't seem to use Json2CSharp to get the classes I'd need as it doesn't make Destination a List, it also changes Trip to an Object instead of a class. Which is really weird. It just throws an error saying the JSON can't be parsed.

using DataContractJsonSerializer knowntype

I am trying to deserealize json:
Classes is generated by json2sharp
But it throws exception:
Element ": Data" contains data from a data type that maps to the name
"http://schemas.datacontract.org/2004/07/TMSoft.CryptoDoc.Gu45:Gu45".
The deserializer is no information of any type, are matched with the
same name. Use DataContractResolver or add type that matches "Gu45",
the list of known types, such as using KnownTypeAttribute attribute or
by adding it to the list of known types passed to
DataContractSerializer.
How to fix it?
namespace json
{
class Program
{
static void Main(string[] args)
{
string json = System.IO.File.ReadAllText(#"D:\Json.txt");
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RootObject));
var account = serializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
}
}
public class Branch
{
public string Code { get; set; }
public string Name { get; set; }
}
public class Direction
{
public object Code { get; set; }
public string Name { get; set; }
}
public class Org
{
public string Code { get; set; }
public string Name { get; set; }
}
public class Wagon
{
public string Comment { get; set; }
public object NoteTimeString { get; set; }
public string Number { get; set; }
public string OwnerCode { get; set; }
public string StateString { get; set; }
}
public class Data
{
public string __type { get; set; }
public Branch Branch { get; set; }
public string DeliveryTimeString { get; set; }
public Direction Direction { get; set; }
public string EsrCode { get; set; }
public int GU45Type { get; set; }
public object ManeuverTime { get; set; }
public string Number { get; set; }
public Org Org { get; set; }
public object ParkName { get; set; }
public object ParkNum { get; set; }
public string RailwayName { get; set; }
public string RegistrationDateTimeString { get; set; }
public object Span { get; set; }
public string StationName { get; set; }
public string TakingTimeString { get; set; }
public object TrackNum { get; set; }
public object TrackNumAddition { get; set; }
public object WagonNote { get; set; }
public List<Wagon> Wagons { get; set; }
}
public class Body
{
public Data Data { get; set; }
public List<int> Signature { get; set; }
}
public class RootObject
{
public Body Body { get; set; }
public int Revision { get; set; }
public int State { get; set; }
public string StateDate { get; set; }
public string WosId { get; set; }
}
}
Json.txt:
{
"Body": {
"Data": {
"__type": "Gu45:#TMSoft.CryptoDoc.Gu45",
"Branch": {
"Code": "9898",
"Name": "Place"
},
"DeliveryTimeString": "07.03.2014 10:00:00",
"Direction": {
"Code": null,
"Name": "Test"
},
"EsrCode": "320007",
"GU45Type": 2,
"ManeuverTime": null,
"Number": "1",
"Org": {
"Code": "1860",
"Name": "Test"
},
"ParkName": null,
"ParkNum": null,
"RailwayName": "Test",
"RegistrationDateTimeString": "07.03.2014",
"Span": null,
"StationName": "Test",
"TakingTimeString": "07.03.2014 12:00:00",
"TrackNum": null,
"TrackNumAddition": null,
"WagonNote": null,
"Wagons": [
{
"Comment": "РЕМТ",
"NoteTimeString": null,
"Number": "44916989",
"OwnerCode": "22",
"StateString": "0"
}
]
},
"Signature": [
48,
106
]
},
"Revision": 1966,
"State": 2,
"StateDate": "2014-03-07T12:48:03Z",
"WosId": "15805729"
}
I had similar experience in my previous projects with DataContractJsonSerializer. it seems that "__type" field has a special meaning for DataContractJsonSerializer.
This is one of the main reasons that I use Json.net
it matters only if it's the first property in the object but if it has any other positions it works and exceptions is not thrown. you can try it but changing __type position below the branch property in Json.txt. I don't know if it's the case and you can find a workaround.
I haven't tried this solution but it worth to give it a try:
hope it helps

Deserializing a complex JSON object

I use JavaScript.Serializer.Deserializer to deserialize a complex JSON object, as below:
{
"name": "rule 1",
"enabled": true,
"conditions": [{
"type": "time",
"time": "17:23:10",
"days": "125"
}, {
"type": "sensor",
"uid": "10.2.0.1",
"setpoint1": 12,
"setpoint2": 18,
"criterion": 1
}, {
"type": "sensor",
"uid": "10.3.0.1",
"setpoint1": 12,
"setpoint2": 18,
"criterion": 2
}],
"actions": {
"period": 100,
"single": false,
"act": [{
"type": "on",
"uid": "10.1.0.1"
}, {
"type": "sms",
"message": "Hello World"
}]
}
}
And I want to convert it to some classes, like below:
public class Rule
{
public string name { get; set; }
public bool enabled { get; set; }
public List<Condition> conditions { get; set; }
public List<Action> actions { get; set; }
}
public class Condition
{
public string type { get; set; }
public string uid { get; set; }
public DateTime? time { get; set; }
public string days { get; set; }
public double setpoint1 { get; set; }
public double setpoint2 { get; set; }
public int criterion { get; set; }
}
public class Action
{
public int period { get; set; }
public bool single { get; set; }
public List<Act> act { get; set; }
}
public class Act
{
public string type { get; set; }
public string uid { get; set; }
public string message { get; set; }
}
The deserialization snippet:
json = new JavaScriptSerializer();
Rule rule = (json.Deserialize<Rule>(jsonStr));
If I simplify the Rule class and declare conditions and actions as simple strings, it works fine.
But if I use the classes like above, it throws an exception:
Cannot convert object of type 'System.String' to type 'System.Collections.Generic.List`1[IoTWebApplication.Condition]'
The structure you create does not fit to the JSON you posted.
It should look like
public class Rule
{
public string name { get; set; }
public bool enabled { get; set; }
public Condition[ ] conditions { get; set; }
public Actions actions { get; set; }
}
public class Actions
{
public int period { get; set; }
public bool single { get; set; }
public Act[ ] act { get; set; }
}
public class Act
{
public string type { get; set; }
public string uid { get; set; }
public string message { get; set; }
}
public class Condition
{
public string type { get; set; }
public string time { get; set; }
public string days { get; set; }
public string uid { get; set; }
public int setpoint1 { get; set; }
public int setpoint2 { get; set; }
public int criterion { get; set; }
}
It is (in most cases) very easy in VS to get the classes direct out of the JSON
Copy JSON to clipboard
In VS EDIT/Special Paste/Paste JSON as Classes (the code above was created by this)
The problem was that the inner (nested) json was quoted and therefore was processed as a string. So when I removed the quotes, it worked fine:
json = new JavaScriptSerializer();
Rule rule = (json.Deserialize<Rule>(jsonStr));

Deserializing an array of different object types

Using the Json.NET library, I'm having trouble deserializing some json returned as an array. The json is an array containing some paging information as an object and array of country objects. Here's a sample of the returned json:
[
{
"page": 1,
"pages": 6,
"per_page": "50",
"total": 262
},
[
{
"id": "ABW",
"iso2Code": "AW",
"name": "Aruba",
"region": {
"id": "LCN",
"value": "Latin America & Caribbean (all income levels)"
},
"adminregion": {
"id": "",
"value": ""
},
"incomeLevel": {
"id": "NOC",
"value": "High income: nonOECD"
},
"lendingType": {
"id": "LNX",
"value": "Not classified"
},
"capitalCity": "Oranjestad",
"longitude": "-70.0167",
"latitude": "12.5167"
}
]
]
I am attempting to deserialize to the following types:
class CountriesQueryResults
{
public PagingInfo PageInfo { get; set; }
public List<CountryInfo> Countries { get; set; }
}
class PagingInfo
{
public int Page { get; set; }
public int Pages { get; set; }
[JsonProperty("per_page")]
public int ResultsPerPage { get; set; }
public int Total { get; set; }
}
class CountryInfo
{
public string Id { get; set; }
public string Iso2Code { get; set; }
public string Name { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
public string CapitalCity { get; set; }
public CompactIdentifier Region { get; set; }
public CompactIdentifier AdminRegion { get; set; }
public CompactIdentifier IncomeLevel { get; set; }
public CompactIdentifier LendingType { get; set; }
}
class CompactIdentifier
{
public string Id { get; set; }
public string Value { get; set; }
}
I am calling DeserializeObject as so:
var data = JsonConvert.DeserializeObject<List<CountriesQueryResults>>(response);
I am getting the following error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'CountriesQueryResults' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I have been trying to get the answer from the documentation but I can't seem to figure it out. Any help would be appreciated.
Since your json is like this [ {....} , [{....}] ], You can only deserialize it to an object array(Where first item is an object and second, another array).
This simplest way I think to convert it to a c# object is:
var jArr = JArray.Parse(jsonstr);
var pageInfo = jArr[0].ToObject<PagingInfo>();
var countryInfos = jArr[1].ToObject<List<CountryInfo>>();
Class definitions would be:
public class PagingInfo
{
public int page { get; set; }
public int pages { get; set; }
[JsonProperty("per_page")]
public int ResultsPerPage { get; set; }
public int total { get; set; }
}
public class Region
{
public string id { get; set; }
public string value { get; set; }
}
public class AdminRegion
{
public string id { get; set; }
public string value { get; set; }
}
public class IncomeLevel
{
public string id { get; set; }
public string value { get; set; }
}
public class LendingType
{
public string id { get; set; }
public string value { get; set; }
}
public class CountryInfo
{
public string id { get; set; }
public string iso2Code { get; set; }
public string name { get; set; }
public Region region { get; set; }
public AdminRegion adminregion { get; set; }
public IncomeLevel incomeLevel { get; set; }
public LendingType lendingType { get; set; }
public string capitalCity { get; set; }
public string longitude { get; set; }
public string latitude { get; set; }
}
PS: You can change the property names' first char to Uppercase if you want. I used http://json2csharp.com/ to automatically generate those classes.

Deserializing Onedrive REST data

I'm working with OneDrive and need to get information about a folders contents back from the server. This is the type of data I am working with:
{
"data": [
{
"id": "folder.xxxx",
"from": {
"name": "john doe",
"id": "xxxx"
},
"name": "Files that are in a folder",
"description": "",
"parent_id": "folder.xxxx",
"size": 0,
"upload_location": "https://apis.live.net/v5.0/folder.xxxx/files/",
"comments_count": 0,
"comments_enabled": false,
"is_embeddable": true,
"count": 0,
"link": "xxxx",
"type": "folder",
"shared_with": {
"access": "Just me"
},
"created_time": "2014-03-06T18:48:16+0000",
"updated_time": "2014-03-06T18:48:16+0000",
"client_updated_time": "2014-03-06T18:48:16+0000"
}, {
"id": "file.xxxx",
(same as above for rest of data structure)
}, {
"id": "file.xxxx",
(Same as above for rest of data structure)
}
]
}
When doing a different request to the server you get back just the ("id" : "folder.xxx") info chunk and I was able to process that data using a class that looks like this:
[DataContract]
public class ResponseFolder
{
[DataMember(Name = "id")]
public string id { get; set; }
[DataMember(Name = "from")]
public from from { get; set; }
[DataMember(Name = "name")]
public string name { get; set; }
//etc.
And handling the entries like "from" with similar structures:
[DataContract]
public class from
{
public string name { get; set; }
public string id { get; set; }
}
I thought I could do the same for the data request at the top and so have this class which is not working for me:
[DataContract]
public class FolderRequest
{
[DataMember(Name = "data")]
public ResponseFolder data { get; set; }
}
And I try to use it on this line:
FolderRequest = jss.Deserialize<FolderRequest>(json);
But FolderRequest is null after that. I have also tried doing
jss.Deserialize<List<ResponseFolder>>(json);
after googling around how to handle arrays in json but that did not work either.
Any help would be appreciated!
Your complete model is
public class From
{
public string name { get; set; }
public string id { get; set; }
}
public class SharedWith
{
public string access { get; set; }
}
public class ResponseFolder
{
public string id { get; set; }
public From from { get; set; }
public string name { get; set; }
public string description { get; set; }
public string parent_id { get; set; }
public int size { get; set; }
public string upload_location { get; set; }
public int comments_count { get; set; }
public bool comments_enabled { get; set; }
public bool is_embeddable { get; set; }
public int count { get; set; }
public string link { get; set; }
public string type { get; set; }
public SharedWith shared_with { get; set; }
public string created_time { get; set; }
public string updated_time { get; set; }
public string client_updated_time { get; set; }
}
public class FolderRequest
{
public List<ResponseFolder> data { get; set; }
}
and you should serialize as
var obj = new JavaScriptSerializer().Deserialize<FolderRequest>(DATA);
Looks like data needs to be an array:
[DataContract]
public class FolderRequest
{
[DataMember(Name = "data")]
public ResponseFolder[] data { get; set; }
}
If you are ok with use Json.Net (http://james.newtonking.com/json), try this:
public class From
{
public string Name { get; set; }
public string Id { get; set; }
}
public class SharedWith
{
[JsonProperty(PropertyName = "access")]
public string AccessName { get; set; }
}
public class ResponseFolder
{
public string Id { get; set; }
public From From { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[JsonProperty(PropertyName = "shared_with")]
public SharedWith SharedWith { get; set; }
}
public class RootObject
{
public List<ResponseFolder> data { get; set; }
}
And then your deserialization:
var result = JsonConvert.DeserializeObject<RootObject>(json);
Hope this helps.

Categories

Resources